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

问题描述 投票:0回答:2

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

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

我的模块.i

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

我的模块.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 相关联?

我尝试使用类型映射但没有成功。

java swig
2个回答
3
投票

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

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

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

后者的转换(

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

使用预定义的类型映射

与您想要的非常相似的标准转换(

byte[]
char *
)由文件中定义的“
char * BYTE
”类型映射处理
various.i
。要使用它,您需要做的就是添加

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

位于 swig 接口文件的顶部,其中

buffer_variable_name
是函数参数中变量的 name(类型映射可以通过名称进行匹配)。有关详细信息,请参阅常规 typemap 文档Java typemap 文档

但是,这并不完全是您想要的,因为您的函数需要一个

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

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

希望这有帮助。


0
投票

这个问题在几个月前就已被修复,理论上在 swig 4.3 中:

https://github.com/swig/swig/commit/ba9b0a35ab62f0d3cfbb4f7109569d86a00ec53c

© www.soinside.com 2019 - 2024. All rights reserved.