如何定义痛饮类型映射返回无符号字符*回Java(How to define swig typemap

2019-06-26 09:49发布

我有一个调用C库进行加密功能的Java应用程序。 这是在C,我们需要从一些Java程序使用实现了自定义库。 我需要一种方法来定义一个SWIG类型映射,让我从Java调用一个函数传递字节组,并把它当作C函数一个无符号的字符指针,其中c函数填充数据并返回到Java

我现在不快乐的接口文件摘译如下:

%module  CryptoFacade

%pointer_functions(int, intp);
%pointer_functions(unsigned char, unsigned_charp);

int enCrypt(char* clearText, int clearLen,unsigned char* retCipherText, int *retCipherLen);

从我不高兴的Java代码摘录如下。 在下面的代码中,我预计要加密函数调用会给我一个缓冲区,但它给了我一个“短”按生成的代码。 (参见代码中的注释)


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);

我想我应该我的接口定义更改为类似下面,我让我的第三个参数jbytearray,然后我得到了实现类型表,将复制的内容,将无符号字符指针在C程序到Java字节组。

我完全没有问题,如果我有指定的内容为256个字节的长度,因为处理任意长度可能会非常棘手。

有人能指出我的地方,我能找到这样的类型映射(我是新痛饮,并以书面形式typemaps没有经验)

%module  CryptoFacade

%pointer_functions(int, intp);
%pointer_functions(unsigned char, unsigned_charp);

int enCrypt(char* clearText, int clearLen, jbyteArray retCipherText, int *retCipherLen);

Answer 1:

做字节数组工作在Java中最简单的方法是使用%array_class (或%array_functions ),它是像%pointer_functions但对于整个阵列,而不只是单个元件。 我把一个完整的例子给你,用这个头文件作为测试:

inline void foo(unsigned char *bytearr) {
  bytearr[0] = 1;
  bytearr[1] = 2;
  bytearr[2] = 3;
  bytearr[3] = 100;
}

我们可以用SWIG包装这个搭配:

%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. \n" + e);
      System.exit(1);
    }
  }
%}

我也把一些Java来行使这一职能:

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));
  }
}

其中编译和运行。 需要注意的是unsigned char在C或C ++是用Java为表示short - Java没有任何无符号类型,所以其适合的范围0-255的最小类型是短。 byte默认不覆盖。 (你可以玩游戏重新映射unsigned charbyte在其他方面,但是这远远不能直观所以默认是不)。

如果你愿意,你可以做更多先进的东西。 例如,如果你知道你可以使用数组的大小arrays_java.i 。 这个例子中创建使用JNI用于返回的数组typemaps unsigned char 。 此示例示出了如何将传递一个阵列中使用JNI typemaps的功能。 (这是用long而不是byte ,但它实际上是一种搜索和替换更改)。



文章来源: How to define swig typemap for returning unsigned char* back to java