2012-10-12 153 views
1

我是Java和JNA的新手。我正在使用JNA從Java加載和使用本地DLL函數。JNA問題 - 僅使用從Java填充的部分數組由DLL使用

我在傳遞指向數組的指針時遇到了問題。按照規範,我從Java填充這個數組,然後嘗試發送一個指向這個數組的指針給DLL。

這是本地通話的樣子,

StartCom(UNUM8 *pCoPData) 
From the spec: pCoPData -> Reference of the buffer holding the data 

Correspoding JNA映射,

int[] buf = new int[2]; 
    buf[0] = 0x1A; 
    buf[1] = 0x10; 

    Pointer pCoPData = new Memory(8); 
    pCoPData.write(0, buf, 0, buf.length); 

      Library.INSTANCE.StartCom(pCoPData); 

當我執行上面的代碼中,我從DLL紀錄注意到只的第一個元素數組0x1A被使用,第二個字節被忽略。 DLL始終只能看到數組的第一個元素。

我假設只能有2 possibilies對於可能會出現此問題,

1. The above approach I have taken to populate and send the address of a Java array to the DLL is incorrect. 
    2. The DLL is expecting a UNUM8* whereas I am sending a UNUM32*. I will try with byte[] instead of int[] and see if there is any difference. 

任何建議,是有很大的幫助?請告訴我。提前謝謝了 !

回答

1

爲什麼當您在輸入中傳遞函數不正確的類型時,您會期待正確的結果?

如果函數期望指向一個或多個8位元素(在Java中爲byte,假設UNUM8在您的本機代碼中爲8位),那麼您需要將等效指針傳遞給一個或多個8位元素位元素。您正在傳遞一個指向您用兩個32位元素初始化的內存的指針。下面是內存看起來像在8位組爲32位的情況下(所有數值代表8位字節):

base+0x0: 0x1A 
base+0x1: 0x10 

寫兩個後:

寫兩個8位值到內存後32位值來存儲:

base+0x0: 0x1A 0x00 0x00 0x00 
base+0x4: 0x10 0x00 0x00 0x00 

所以你可以看到,如果本機代碼開始從base閱讀,它看到的值是顯著不同,這取決於你如何初始化的內存。

順便說一句,如果本地代碼做需要不斷給你比功能不再通過內存調用自身的引用,你可以使用byte[]作爲UNUM8*參數,而不是分配和初始化Memory

+0

謝謝technomage。就像你提到的,我甚至沒有創建一個指向byte []的指針,因爲本機代碼不需要超出函數調用範圍。它的好,如果它的GC'd。使用byte []直接工作,因爲它已經是一個引用類型。再次感謝有關內存使用的數據類型的詳細說明和重點。 – user1724114