使用 SWIG 在 Java 和 C++ 之间传递缓冲区
Posted
技术标签:
【中文标题】使用 SWIG 在 Java 和 C++ 之间传递缓冲区【英文标题】:Passing buffer between Java and C++ using SWIG 【发布时间】:2018-05-15 10:02:57 【问题描述】:我想使用 SWIG 在 Java 和 C++ 之间传递一段信息(例如 1024 字节的内存)。 C++中定义的结构如下:
struct Buffer
unsigned char *addr;
size_t size;
我应该如何为此编写 SWIG 接口文件?
【问题讨论】:
是的。才意识到。谢谢梅莱比乌斯。 :) 【参考方案1】:尚不完全清楚您想要实现的具体目标。
如果您想将 Buffer
映射到 Java byte[]
,您可以使用自定义类型映射:
%typemap(jni) Buffer "jbyteArray"
%typemap(jtype) Buffer "byte[]"
%typemap(jstype) Buffer "byte[]"
%typemap(in) Buffer
$1.addr = (unsigned char *) JCALL2(GetByteArrayElements, jenv, $input, 0);
$1.size = JCALL1(GetArrayLength, jenv, $input);
%typemap(argout) Buffer
JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *) $1.addr, 0);
%typemap(out) Buffer
$result = JCALL1(NewByteArray, jenv, $1.size);
JCALL4(SetByteArrayRegion, jenv, $result, 0, $1.size, (jbyte *) $1.addr);
delete[] $1.addr;
%typemap(javain) Buffer "$javainput"
%typemap(javaout) Buffer return $jnicall;
然后是 C++ 代码
Buffer getData();
void sendData(Buffer arg);
将映射到Java:
public static byte[] getData() ...
public static void sendData(byte[] arg) ...
将数据传递给 Java 的困难在于将其放入 JVM 堆和/或管理数据的生命周期。通过一些复制很容易实现,但真正的 0-copy 解决方案通常需要更改 C++ 接口。
完整示例:
example.h
#include <stddef.h>
struct Buffer
unsigned char *addr;
size_t size;
;
Buffer getData();
void sendData(Buffer);
example.cxx
#include "example.h"
Buffer getData()
Buffer rc new unsigned char[64], 64 ;
for (int i = 0; i < rc.size; ++i)
rc.addr[i] = 0x40 + i;
return rc;
void sendData(Buffer buf)
// use buf.addr
example.i
%module example
%
#include "example.h"
%
%typemap(jni) Buffer "jbyteArray"
%typemap(jtype) Buffer "byte[]"
%typemap(jstype) Buffer "byte[]"
%typemap(in) Buffer
$1.addr = (unsigned char *) JCALL2(GetByteArrayElements, jenv, $input, 0);
$1.size = JCALL1(GetArrayLength, jenv, $input);
%typemap(argout) Buffer
JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *) $1.addr, 0);
%typemap(out) Buffer
$result = JCALL1(NewByteArray, jenv, $1.size);
JCALL4(SetByteArrayRegion, jenv, $result, 0, $1.size, (jbyte *) $1.addr);
delete[] $1.addr;
%typemap(javain) Buffer "$javainput"
%typemap(javaout) Buffer return $jnicall;
%ignore Buffer;
%include "example.h"
test.java
class test
public static void main(String[] args) throws Exception
System.loadLibrary("_example");
byte[] data = example.getData();
System.out.println(new String(data));
输出:
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz|~⌂
【讨论】:
以上是关于使用 SWIG 在 Java 和 C++ 之间传递缓冲区的主要内容,如果未能解决你的问题,请参考以下文章
在 SWIG 中携带自定义 Python 数据的 C++ 对象
SWIG:如何将 C++ 对象数组从 C# 传递到 C++?
使用 SWIG 将 C++ 对象指针传递给 Python,而不是再次返回 C++
使用 SWIG 将 numpy 数组元素(int)传递给 c++ int