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

Bla*_*0ut 9 java swig

我正在尝试使用SWIG将带有二进制数据和字符串参数的byte []参数从Java传递到C++代码.

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

my_module.i

%module mymodule
%inline %{
   extern void compress_buffer_to_file(unsigned char *buffer, char *ofname);
%}
Run Code Online (Sandbox Code Playgroud)

my_module.cpp

void compress_buffer_to_file(unsigned char *buffer, char *ofname){
   .........
}
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

m7t*_*hon 3

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

  1. Javabyte[]unsigned char *
  2. Stringchar *

用于此类转换的通用工具是 SWIG类型映射。方便的是,SWIG 已经提供了许多功能,只需应用即可。查看Java 类型映射文档

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

使用预定义的类型映射

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

%include various.i
%apply char *BYTE { char *buffer_variable_name };
Run Code Online (Sandbox Code Playgroud)

在 swig 接口文件的顶部,其中buffer_variable_name是函数参数中变量的名称(类型映射可以通过名称进行匹配)有关详细信息,请参阅常规类型映射文档Java 类型映射文档

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

%apply unsigned char *NIOBUFFER { unsigned char *buffer_variable_name };
Run Code Online (Sandbox Code Playgroud)

编写你的“自己的”类型映射

在您的情况下,您希望与提供的“”类型映射基本相同char * BYTE,但对于采用unsigned char *. 因此,您只需将它们复制到various.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 {
  $1 = (unsigned char *) JCALL2(GetByteArrayElements, jenv, $input, 0); 
}

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

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

/* Prevent default freearg typemap from being used */
%typemap(freearg) unsigned char *UBYTE "" 
Run Code Online (Sandbox Code Playgroud)

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

%include ubyte.i
%apply unsigned char *UBYTE { unsigned char *buffer_variable_name };
Run Code Online (Sandbox Code Playgroud)

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

希望这可以帮助。