How to define swig typemap for returning unsigned char* back to java(如何定义 swig 类型映射以将 unsigned char* 返回到 java)
问题描述
I have a Java Application that calls a c library for performing crypto functions. This is a custom library implemented in c that we need to use from some Java programs. I need a way to define a SWIG typemap that will allow me call a function passing bytearray from Java and treat it as an unsigned character pointer in C function where c function fills data and returns it to java
Excerpt of my present unhappy interface file is as follows
%module CryptoFacade
%pointer_functions(int, intp);
%pointer_functions(unsigned char, unsigned_charp);
int enCrypt(char* clearText, int clearLen,unsigned char* retCipherText, int *retCipherLen);
And Excerpt from my unhappy Java code is as follows. In the code below I expected that the call to enCrypt function will give me a buffer but it gives me a "short" as per generated code. (See comments in the code)
class MainLoader {
static {
System.loadLibrary("dccasecuJ"); //Load my crypto library
}
public static void main(String[] args) {
// Define the parameters to be passed by reference
SWIGTYPE_p_int retCipherLen=CryptoFacade.new_intp();
SWIGTYPE_p_unsigned_char retCipherText =
CryptoFacade.new_unsigned_charp();
CryptoFacade myFacade=new CryptoFacade();
// Call crypto library function. First two are value parameters, next two are return
myFacade.enCrypt("STRING-TO-ENCRYPT", 17, retCipherText, retCipherLen);
// The length I get back in fourth parameter is just fine
int gotLen= CryptoFacade.intp_value(retCipherLen);
//The value I get for the Ciphertext though is a "short" ... no good
// I need a byte[] in java that has the ciphertext
short gotText= CryptoFacade.unsigned_charp_value(retCipherText);
I guess I should change my interface definition to something like below where I make my third parameter a jbytearray and then I got to implement a typemap that will copy the contents pointed to by unsigned character pointer in C program to a java bytearray.
I am perfectly fine if I have to specify the length of content to 256 bytes, because handling arbitrary lengths may be tricky.
Can someone point me to place where I can find such a typemap (I am new to SWIG and have no experience in writing typemaps)
%module CryptoFacade
%pointer_functions(int, intp);
%pointer_functions(unsigned char, unsigned_charp);
int enCrypt(char* clearText, int clearLen, jbyteArray retCipherText, int *retCipherLen);
The easiest way to do work with byte arrays in Java is to use %array_class
(or %array_functions
) which is like %pointer_functions
but for an entire array, not just a single element. I put together a complete example for you, using this header file as a test:
inline void foo(unsigned char *bytearr) {
bytearr[0] = 1;
bytearr[1] = 2;
bytearr[2] = 3;
bytearr[3] = 100;
}
We can wrap this with SWIG with:
%module test
%{
#include "test.h"
%}
%include <carrays.i>
%array_class(unsigned char,ByteArr);
%include "test.h"
// Emit Java code to automatically load the shared library
%pragma(java) jniclasscode=%{
static {
try {
System.loadLibrary("test");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load.
" + e);
System.exit(1);
}
}
%}
I also put together some Java to exercise this function:
public class run {
public static void main(String[] argv) {
ByteArr arr = new ByteArr(4); // Initial size 4
// You could set some values before passing in if you wanted to.
test.foo(arr.cast());
System.out.println(arr.getitem(0) + ", " + arr.getitem(1) + ", " + arr.getitem(2) + ", " + arr.getitem(3));
}
}
which compiled and ran. Note that unsigned char
in C or C++ is represented in Java as short
- Java doesn't have any unsigned types, so the smallest type which fits the range 0-255 is a short. byte
doesn't cover it by default. (You could play games re-mapping unsigned char
to byte
in other ways but that's far from intuitive so the default is not to).
You can do more advanced things if you want. For example if you know the size of the array you can use arrays_java.i
. This example creates typemaps using JNI for returning an array of unsigned char
. This example shows how to pass an array in to a function using JNI typemaps. (It's using long
instead of byte
, but the it's literally a search and replace to change that).
这篇关于如何定义 swig 类型映射以将 unsigned char* 返回到 java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何定义 swig 类型映射以将 unsigned char* 返回到 java
基础教程推荐
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01