我的Java應用程序使用JNA通過製造商提供的API與設備驅動程序進行通信。 API使用Windows消息進行通信。在執行過程中的一個點上,設備有一組作爲LPARAM傳遞的數據。 LPARAM是指向包含我需要的數據的結構向量的指針。我如何處理JNA中的不透明指針?
在C++中,我可以訪問這個數據是這樣的:
ImagesStruct *Images = { 0 };
...
Images = (ImagesStruct *)lParam;
天然ImagesStruct看起來是這樣的:
typedef struct _CompressedImage
{
BYTE *pBuffer;
int BufferLen;
}
CompressedImage;
typedef struct _ImagesStruct
{
DWORD DocNumber;
CompressedImage *Images;
BOOL SnippetFront;
}
ImagesStruct;
在Java中,我有這樣映射結構:
// ImagesStruct
public class IMAGES extends Structure {
public int DocNumber;
public COMPRESSED_IMAGE.ByReference Images; // pointer
public boolean SnippetFront;
public IMAGES() { super(); }
public IMAGES(Pointer p) { super(p); }
@Override
protected List getFieldOrder() {
return Arrays.asList("DocNumber", "Images", "SnippetFront");
}
}
// CompressedImage
public class COMPRESSED_IMAGE extends Structure {
public Pointer pBuffer; // pointer
public int BufferLen;
public COMPRESSED_IMAGE() { super(); }
public COMPRESSED_IMAGE(Pointer p) { super(p); }
@Override
protected List getFieldOrder() {
return Arrays.asList("pBuffer", "BufferLen");
}
public static class ByReference extends COMPRESSED_IMAGE implements Structure.ByReference {
public ByReference() { super(); }
public ByReference(Pointer p) { super(p); read(); }
}
}
這是我嘗試訪問Java中的這些數據的衆多方法之一
Pointer p = lparam.toPointer(); // this works
IMAGES pImages = new IMAGES();
IMAGES[] pa = (IMAGES[]) pImages.toArray(pImages.size()); // error here
一切我嘗試,包括上面,似乎導致同樣的錯誤信息:
JNA:回調[email protected]發生以下異常: java.lang.UnsupportedOperationException:該指針是不透明的: 常量@ 0x155f0000在 com.sun.jna.Pointer $ Opaque.read(Pointer.java:1320)在 com.sun.jna.Pointer.getByteArray(Pointer.java:726)在 desktop.IDeal.callback(IDeal.java:199)at sun .reflect.NativeMethodAccessorImpl.invoke0(本機方法)在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang.reflect中.Method.invoke(Method.java:497)在 com.sun.jna.CallbackReference $ DefaultCallbackProxy.invokeCallback(CallbackReference.java:470) 在 com.sun.jna.CallbackReference $ DefaultCallbackProxy.callback(CallbackReference.java: 500) at com.sun.jna.Native.invokeInt(Native Method)at com.sun.jna.Function.invoke(Function.java:384)at com.sun.jna.Function.invoke(Function.java :316)at com.sun.jna.Library $ Handle r.invoke(Library.java:232)at com.sun.proxy $ Proxy2.GetMessage(Unknown Source)at win32.Window.run(Window.java:59)at java.lang.Thread.run( Thread.java:745)
我有東西映射正確嗎?如果我沒有辦法將指針的另一端的數據映射到一組Java對象,那麼如何使用Pointer
對象來訪問該數據?
謝謝你的建議。我添加了以前錯過的'read()'的調用,並且仍然得到*指針是不透明*消息。修改回調來取代IMAGES而不是LPARAM會做一些不同於'new IMAGES(lParam.toPointer())'的東西嗎? – Cypher 2015-04-07 17:13:52
是的,改變回調簽名*會*做一些不同的事情,這就是爲什麼我首先提出的建議。 – technomage 2015-04-07 17:34:54
我問的原因是因爲設備發送了許多消息到這個回調管理的窗口句柄,並且LPARAM經常用於不同類型的數據(主要是int),這些數據不會正確映射到IMAGES對象。因此,如果我無法映射LPARAM - > IMAGES,如果API開發人員確實使用了不透明指針,是否有手動從指針中讀取數據的方法?我已經嘗試了指針對象上的各種方法,比如read(),getByte()等等,它們都會以相同的異常失敗。 – Cypher 2015-04-08 18:11:15