SWIG/Java 从 C++ 获取未知大小的缓冲区

SWIG/Java get buffer of unknown size from C++

我有一个C++函数 foo(unsigned char*& ptr) 创建一个缓冲区并用二进制数据填充它并设置 ptr 指向它。 我需要从 Java 获取缓冲区的内容。

澄清一下,C++ 代码可以这样使用:

unsigned char* ptr;
foo(ptr);
//now ptr points to a buffer, do what you want, eg
x=ptr[1];

使用arrays_java.i 将不起作用,因为 SWIG 需要提前知道数组大小。我还尝试了针对 unsigned char* 修改为 unsigned char*& 的内置类型映射 NIOBUFFER,但这对生成的 C++ 包装器代码提出了问题,JVM 在尝试使用它时崩溃了。我也不认为在 this answer 中使用 carrays.i 会起作用,因为参数是 unsigned char*&,而不仅仅是 unsigned char*,但我还没有尝试过。 (编辑 使用 %array_functions (int * Iarr) 作为测试函数

void test(int*& ia)
{
ia[0]=1;
...
}

导致 JVM 崩溃 EXCEPTION_ACCESS_VIOLATION 就像 NIOBUFFER 类型映射一样)

有没有办法从 C++/JNI 包装器代码中获取缓冲区的大小,然后从 JNI 代码中创建一个已知大小的 Java 数组,以便我可以利用 arrays_java.i

有没有办法使用 NIOBUFFER,可能需要修改其类型映射 and/or 生成的 C++ 包装器?

有没有办法将某些 type*& 视为 type*,以便我可以使用 carrays.i

因为 NIOBUFFER 类型映射和 array_functions 都使 JVM 崩溃,我觉得我的问题的根源是 type*& 参数,解决这个问题的方法将允许其中任何一个两个选项。我该怎么做?

我想出了一个解决办法。假设我的问题中的函数 foo 相同:

  1. 写一个函数,比如 bar,它创建一个本地指针,将其传递给 foo,然后 returns。在这种情况下,bar 将是

    unsigned char* bar() { unsigned char* ptr; foo(ptr); return ptr; }

  2. 在 SWIG 中:使用 %array_classes ,即 array_class(unsigned char, ShortArray)

  3. 通过使用frompointerbar返回的指针创建数组class的实例。 ShortArray sa = ShortArray.frompointer(example.bar())

这避免了让 SWIG 将 type*& 作为 argin/out 工作的麻烦,因为您现在正在处理 SWIG 处理得很好的普通指针和数组 "out of the box"。它还允许 Java 端接收任意大小的缓冲区,并提供更多类似于 Java 的语法。