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


基础教程推荐
- 如何在 Spring @Value 注解中正确指定默认值? 2022-01-01
- 大摇大摆的枚举 2022-01-01
- 不推荐使用 Api 注释的描述 2022-01-01
- 在 Java 中创建日期的正确方法是什么? 2022-01-01
- 多个组件的复杂布局 2022-01-01
- Java Swing计时器未清除 2022-01-01
- 从 python 访问 JVM 2022-01-01
- 验证是否调用了所有 getter 方法 2022-01-01
- Java 实例变量在两个语句中声明和初始化 2022-01-01
- 如何在 JFrame 中覆盖 windowsClosing 事件 2022-01-01