2016-08-03 54 views
0

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

为了澄清,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在尝试使用它时崩溃。我也不认为使用carrays.ithis answer一样可以工作,因为参数是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,可能修改其类型映射和/或生成的C++包装?

有没有办法将一些type*&作为type*来处理,所以我可以使用carrays.i

因为无论是NIOBUFFER类型映射和array_functions坠毁的JVM,我有一种感觉,我的问题的根源是type*&参数和解决此问题的方法将允许其中的任意一种两个选项。我该怎么做呢?

+0

如果您的主程序是C语言并且您不使用JNI,而不知道大小,您将如何使用缓冲区? – immibis

+0

在不知道数组大小的情况下,无法创建Java数组。 – immibis

+0

我特别说我正在使用SWIG,它生成了JNI代码,我正在考虑的一种可能性是修改该代码,使其符合我的要求。这可能包括获取C++缓冲区大小,并用另一个适当的大小替换从Java传递的数组,并将该数组传回给Java。 当然,我对更简单的方法感兴趣。 – BenK

回答

0

我想出了一个解决方案。假设同样的功能foo在我的问题:

  1. 写一个函数,说bar,创建一个本地指针,它传递到foo,并将其返回。在这种情况下,bar将是

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

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

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

这绕过越来越痛饮与type*&工作作为argin /输出,因为你现在正在处理普通的指针和数组这痛饮处理就好了“开箱即用”的头痛。它还允许Java端接收任意大小的缓冲区,并提供更多类似Java的语法。

+0

除非''foo'使指针'ptr'指向一个缓冲区,这个缓冲区可以是静态的,也可以在库退出时正确处理,否则会泄漏内存。我用Python解决了你的问题1000次,如果你想看到这个解决方案,我可以给你。 –

+0

那么,Java端在'array_classes.i'中有'delete'这个函数。这会防止内存泄漏吗? – BenK

+0

在Java部分的SWIG手册中,您几乎要完成一个完整的示例。 –