2016-03-22 157 views
5

我開始使用JNA與計算機的RS485接口上的設備進行通信。令我意外的是,我很快就收到了良好的結果。但是現在我陷入了一個簡單的問題。我使用的庫接受一個指向struct指針的指針。而實際的簽名JNA:將結構指針設置爲NULL

func(Struct1 **, Struct2 **, Struct3 *, Struct4 *, long)

我們指明庫的預期,最後的指針是NULL指針,第一個參數的大小。這是失敗的。下面的代碼是什麼我試過到目前爲止:

Struct1.ByReference[] s = (Struct1.ByReference[]) new Struct1.ByReference().toArray(size); 
    int pos = 0; 

    // ... 
    // for loop to set the s[pos] struture values 
    for(pos = 0; pos < size - 1; pos++) 
    // ... 

    // Now set the last array element to a null pointer to indicate end-of-list 
    s[pos].getPointer().setPointer(0, null);// Following does not work: results in zero memoried structure 
    s[pos] = null; // Following does not work wither: NullPointerException at com.sun.jna.Structure.autoWrite 

編輯1

s[pos] = new Struct1.ByReference(Pointer.NULL); // results in zero memoried structure as well 

EDIT 2

根據technomage的問題。如果我要寫C代碼,它可能看起來像這樣:

Struct1 **s = malloc(n * sizeof(Struct1*)); 

for(int i=0; i<n; i++) 
{ 
    if(i == n -1) 
    { 
     s[i] = NULL; 
    } 
    else 
    { 
     s[i] = malloc(sizeof(Struct1)); 
     s[i].bla = value; 
     .... 
    } 
} 

但要警告:我不是很熟練的C/C++。我認爲Java是我的領域。

有沒有人有類似的問題?也許我只是沒有看到樹木...

在此先感謝。

+0

請包括本地使用的樣本。沒有該上下文,指針變化的函數聲明可能不明確 - 無法區分指向數組的指針,指向單個指針值的指針或其他幾種變體。 – technomage

+0

你是什麼意思'示例用法'?該庫是從運行FreeRTOS的嵌入式設備代碼中採用的,FreeRTOS是一個開源的實時操作系統。除了導出庫方法的頭文件外,我沒有任何本地代碼。 –

+0

如果你要用'C'編寫代碼,以你想要的方式訪問庫,那麼_that_會是什麼樣子? – technomage

回答

0

JNA中的結構是指針,所以你真正需要的是一個指向一個(指向一個)結構​​的指針,它是一個PointerByReference - 在你的情況下,它們是一個數組。

鑑於上面的代碼示例,您將創建您的結構陣列,少一比N:

Struct1[] struct1Array = new Struct1[n-1]; 

這僅分配了數組的Java內存。

接下來,您將實例化和編寫您對本機內存的變化:

for (int i = 0; i < n-1; i++) { 
    struct1Array[i] = new Struct1(); 
    struct1Array[i].bla = value; 
    struct1Array[i].write(); 
} 

new Struct1()這些結構分配機端內存。也可以使用Structure.toArray()方法來做到這一點;我故意做這個更加手動和低級的嘗試來清楚發生了什麼。

然後,您將創建一個對應的PointerByReference數組來保存指向這些結構的指針。您將爲空值添加一個額外的元素:

PointerByReference[] pbrArray = new PointerByReference[n]; 

同樣,這只是java端分配。

for (int i = 0; i < n-1; i++) { 
    pbrArray[i] = new PointerByReference(struct1Array[i].getPointer()); 
} 
pbrArray[n - 1] = new PointerByReference(Pointer.NULL); 

new PointerByReference()這裏分配的指針本身本機端的內存,這點給你分配的本地端結構:然後你用指針的指針到結構,從Structure.getPointer()方法獲得的填充早。

從我的理解你最初的問題,你會通過這個PointerByReference數組到你的函數,這可能會更新你的結構。

由於您以這種方式創建了兩個數組,因此您可以通過數組索引來跟蹤它們的對應關係。您可能必須遍歷結構數組和本機內存到Java端結構中,以便對其進行進一步處理。通常,當您直接使用傳遞給方法的結構進行自動編寫和自動發送時,但當使用間接引用結構的方式時,JNA並不友好。

作爲通過相應索引跟蹤兩個數組的替代方法,您可以「忘記」初始Structure賦值並稍後使用數組上的PointerByReference.getValue()方法恢復指向結構內存的指針,然後實例化在其構造函數中使用該指針的新結構(例如new Struct1(pbr.getValue()),該指針使用該指針調用super())。