将 byte[] 从 Java 传递给 C++

Passing byte[] from Java to C++

我正在尝试使用 SWIG.

将带有二进制数据的 byte[] 参数和来自 Java 的字符串参数传递给 C++ 代码

这是我的 .i 和 .cpp 文件:

my_module.i

%module mymodule
%inline %{
   extern void compress_buffer_to_file(unsigned char *buffer, char *ofname);
%}

my_module.cpp

void compress_buffer_to_file(unsigned char *buffer, char *ofname){
   .........
}

Java包装器中生成的方法:

public static void compress_buffer_to_file(SWIGTYPE_p_unsigned_char buffer, String ofname) {
   my_moduleJNI.compress_buffer_to_file(SWIGTYPE_p_unsigned_char.getCPtr(buffer), ofname);
}

我如何定义一个 .i 文件来生成一个 Java 包装器,让我将 byte[] 而不是 SWIGTYPE_p_unsigned_char 传递给 compress_buffer_to_file 方法或替代?如何将 Java 端的现有 byte[] 与 SWIGTYPE_p_unsigned_char 相关联?

我试过使用 typemap 但没有成功。

您希望 SWIG 在 Java 和 C++ 类型之间执行转换,即

  1. Java byte[]unsigned char *
  2. Stringchar *.

此类转换的通用工具是 SWIG typemaps. Conveniently, many are already provided by SWIG and simply need to be applied. Have a look at the Java typemap documentation

后面的转换(Stringchar *)由 SWIG 自动完成(使用与 char * 参数匹配的预定义类型映射)。

使用预定义的类型映射

与您想要的非常相似的标准转换(byte[]char *)由文件 various.i 中定义的“char * BYTE”类型映射处理。要使用它,您需要做的就是添加

%include various.i
%apply char *BYTE { char *buffer_variable_name };

在swig接口文件的顶部,其中buffer_variable_name是函数参数中变量的名称(类型映射可以通过名称匹配)。详情见总typemap documentation and the Java typemap documentation.

然而,这并不是您想要的,因为您的函数需要 unsigned char *。如果您可以在 Java 端使用 java.nio.Buffer 而不是 byte[](需要通过 allocateDirect 分配),则在 [=24] 中预定义了一组不同的类型映射=] 可以通过

使用
%apply unsigned char *NIOBUFFER { unsigned char *buffer_variable_name };

正在编写您的 "own" 类型映射

在您的情况下,您需要与提供的“char * BYTE”类型映射基本相同,但对于采用 unsigned char * 的函数。所以你可以将它们从 various.i 复制到一个新文件 ubyte.i 并稍微调整它们:

ubyte.i

%typemap(jni) unsigned char *UBYTE "jbyteArray"
%typemap(jtype) unsigned char *UBYTE "byte[]"
%typemap(jstype) unsigned char *UBYTE "byte[]"
%typemap(in) unsigned char *UBYTE {
   = (unsigned char *) JCALL2(GetByteArrayElements, jenv, $input, 0); 
}

%typemap(argout) unsigned char *UBYTE {
  JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *) , 0); 
}

%typemap(javain) unsigned char *UBYTE "$javainput"

/* Prevent default freearg typemap from being used */
%typemap(freearg) unsigned char *UBYTE "" 

以同样的方式使用它们,在你的 swig 接口文件的顶部添加:

%include ubyte.i
%apply unsigned char *UBYTE { unsigned char *buffer_variable_name };

使用这些预定义类型映射作为基本示例并阅读文档,然后您可以根据需要开始编写自己的自定义类型映射。

希望这对您有所帮助。