将字节 [] 从 Java 传递到 C++

Posted

技术标签:

【中文标题】将字节 [] 从 Java 传递到 C++【英文标题】:Passing byte[] from Java to C++ 【发布时间】:2015-11-03 16:46:52 【问题描述】:

我正在尝试使用 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 没有成功。

【问题讨论】:

我认为我在这里用字节替换 int 的答案应该可以***.com/a/33488560/5171540 【参考方案1】:

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

    Java byte[]unsigned char *Stringchar *

此类转换的通用工具是 SWIG typemaps。方便的是,SWIG 已经提供了许多功能,只需要应用。看看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和Java typemap documentation。

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

%apply unsigned char *NIOBUFFER  unsigned char *buffer_variable_name ;

编写“自己的”类型映射

在您的情况下,您希望与提供的“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 
  $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 "" 

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

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

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

希望这会有所帮助。

【讨论】:

以上是关于将字节 [] 从 Java 传递到 C++的主要内容,如果未能解决你的问题,请参考以下文章

将字节数组从 c++ 传递到 c# 程序集都有哪些不同的方法?

将字节数组从 Unity C# 传递到 C++ 库方法

将字节数组从 C# 传递到 C++ DLL 作为 char*

使用 Dllimport 将一个非常大的字符串作为字节数组从 C++ 传递到 C#

从 C++ 将字节数组传递给 lua 脚本方法

将字节数组从 c++ 传递给 python