![](/img/trans.png)
[英]Why is the ciphertext 32 bytes long when encrypting 16 bytes with AES?
[英]Why do I need to reserve more than 4 bytes for a JNA pointer to receive a long when sizeof(long) is 4?
我正在使用JNA與使用Visual Studio 2015編譯的本機C庫進行通信。我正在使用64位計算機。 我試圖通過長指針long *pdays
參數來接收C函數的值。 我收到以下異常:
java.lang.IndexOutOfBoundsException:界限超出了可用空間:com.sun.jna.Memory.boundsCheck(Memory.java:220)的大小為com.sun.jna.Memory.boundsCheck(Memory.java:220)的offset = 8(Memory.java: 498)
我不明白我在這里缺少什么,如果我只為指針保留4個字節的內存,則會導致上面的崩潰,但是,如果我保留8個,一切都會很好。 但是sizeof(long)返回4,那么為什么我需要保留4個以上的字節?
System.out.println(NativeLong.SIZE); // --> 4
System.out.println(Native.LONG_SIZE); // --> 4
// Pointer pDays = new Memory(Native.LONG_SIZE); Results in IndexOutOfBoundsException
Pointer pDays = new Memory(8); //
nativeLib.GetDaysUntilExpiration(pDays);
return pDays.getLong(0); // crashes here when reserving just 4 bytes
它崩潰是因為您試圖從僅分配了4個字節的本機內存中讀取8個字節。
原生類型是什么,還是只有4個字節都沒有關系。 Memory
僅包含4個字節,您可以按照自己希望的任何方式進行解釋。 您可能會得到一個byte[]
數組,或者一個int
(具有這4個字節),或者甚至是一個short
或byte
只能讀取該數量的字節。 您甚至可以嘗試使用String
(盡管沒有空終止符,但您讀取的內容可能遠遠超過允許的4個字節,而且誰知道您會得到什么,因此很危險。)
您已經要求獲取一個Java long
為8字節的變量。 因此,代碼將檢查偏移量的下8個字節是否適合分配的內存。 來自Memory.java
的代碼具有以下硬編碼:
boundsCheck(offset, 8);
javadoc清楚為什么會這樣:
間接指向
malloc
空間的本地指針laPointer.getLong
。 但是此方法執行邊界檢查,以確保該間接操作不會導致訪問已分配空間之外的malloc
。
在不手動分配空間的情況下,執行操作的正確方法是僅使用NativeLongByReference
。 JNA會自行負責空間的分配和值的獲取,您不必擔心本機的大小。
NativeLongByReference pDays = new NativeLongByReference();
nativeLib.GetDaysUntilExpiration(pDays);
return pDays.getValue().longValue();
編輯:我在您的注釋中注意到您說“ C函數參數是一個指針,使用NativeLongByReference將導致” LongByReference無法轉換為Pointer” –這不是C函數的問題,但與JNA映射有關在您的界面中,最好將GetDaysUntilExpiration
的JNA映射更改為NativeLongByReference
參數,如果您不能更改該函數的JNA映射,則可以使用pDays.getPointer()
作為參數來解決。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.