2016-04-15 213 views
3

我要走this如何將包含com.sun.jna.StringArraycom.sun.jna.Structure從Java轉換爲使用JNA的本機C代碼的示例,以及無法在C代碼中成功獲取結構內容。如何從Java傳遞com.sun.jna.Structure以使用JNA構造C語言

請注意,我可以成功地將C代碼中的結構傳遞給Java中的結構,但是我無法在Java代碼中創建結構併成功將其作爲結構發送給C代碼。

這是有問題的代碼:

String[] user_name_array = new String[3]; 
user_name_array[0] = "test_user_1"; 
user_name_array[1] = "test_user_2"; 
user_name_array[2] = "test_user_3"; 
StringList.ByReference members = new StringList.ByReference(); 
members.length = 3; 
members.strings = new StringArray(user_name_array); 
MyNativeLibrary.myMethod(members); 

似乎很簡單,但它不工作。

它按預期成功進入C代碼,但結構中的指針爲空,長度爲零。

這裏是在Java中的StringList結構:

public static class StringList extends Structure { 
    public volatile long length; 
    public volatile Pointer strings; 
    public static class ByValue extends StringList implements Structure.ByValue {} 
    public static class ByReference extends StringList implements Structure.ByReference { 
     public ByReference() { } 
     public ByReference(Pointer p) { super(p); read(); } 
    } 
    public StringList() { } 
    public StringList(Pointer p) { super(p); read(); } 
} 

下面是在C代碼對應的結構:

typedef struct string_list { 
    uint64_t length; 
    const char **strings; 
} string_list; 

,這裏是在C代碼的方法定義:

const char* my_method(struct string_list *members) 
{ 
    //................. 
} 

使用ndk-gdb,並闖入此功能,這就是它顯示:

(gdb) break my_method 
(gdb) cont 
Continuing. 

Breakpoint 1, my_method (members=0x9bee77b0) at ../app/my_code_file.c:368 
(gdb) p *members 
$1 = {length = 0, strings = 0x0} 

好像它應該工作,所以爲什麼不使它成爲C代碼值是多少?我錯過了什麼?

另外請注意,我可以成功地從Java代碼直接發送一個字符串數組到C代碼,如果它不是一個結構裏面:

的Java:

//This works! 
StringList members = MyNativeLib.myTestFunction(3, new StringArray(user_name_array)); 

C:

//This works! 
string_list* my_test_function(uint64_t length, const char **strings) 
{ 
    //...... 
} 

看起來在這種情況下,JNA按預期工作。那麼,爲什麼它不適用於結構as the documentation states it should

+0

[將字符串數組從JNI傳遞到C的可能的重複](http://stackoverflow.com/questions/5972207/passing-string-array-from-java-to-c-with-jni) –

+2

@ DougStevenson看起來這是一個如何傳遞StringArray的解決方案,而不是傳遞包含StringArray的Structure的方法,因此不是一個好的複製目標。 –

+1

您不會自動將java結構映射到C結構。您必須以編程方式使用JNI從傳遞的jobject對象中抽取感興趣的成員,並且字符串數組是處理的最重要的事情。這是一種痛苦。 –

回答

3

不要將這些字段標記爲易失性。當你這樣做的時候,JNA不會寫信給他們,除非你做一個明確的Structure.writeField()。