gpt4 book ai didi

java - 使用 SWIG 在 Java 和 C++ 之间传递缓冲区

转载 作者:行者123 更新时间:2023-11-30 05:01:19 24 4
gpt4 key购买 nike

我想使用 SWIG 在 Java 和 C++ 之间传递一段信息(例如 1024 字节的内存)。 C++中定义的结构如下:

struct Buffer
{
unsigned char *addr;
size_t size;
}

为此,我应该如何编写 SWIG 接口(interface)文件?

最佳答案

目前还不完全清楚您想要实现的目标。

如果你想将你的 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 复制解决方案通常需要更改 C++ 接口(interface)。

完整示例:

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
}

示例.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"

测试.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{|}~⌂

关于java - 使用 SWIG 在 Java 和 C++ 之间传递缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50353615/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com