2016-08-03 39 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手冊中,您幾乎要完成一個完整的示例。 –