我的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