我正在构建一个Java应用程序,它使用JNA与特定制造商的API进行通信。我有大量的函数调用映射并且已经有效,但是有一对函数让我有些悲伤。
这两个函数都来回传递数据结构以配置设备。该结构在其中具有嵌套的数据结构数组。
原生定义:
VISION_API_DECL BOOL VISION_API SetDeviceParameters( DWORD DeviceID, DeviceParameters DeviceParam );
VISION_API_DECL BOOL VISION_API GetDeviceParameters( DWORD DeviceID, DeviceParameters *DeviceParam );
我在Java中声明它们是这样的:
public interface Driver extends Library {
...
public boolean SetDeviceParameters(int DeviceID, DEVICE_PARAMETERS DeviceParam);
public boolean GetDeviceParameters(int DeviceID, DEVICE_PARAMETERS DeviceParam);
...
}
这些函数调用似乎可以正常工作。当我调用其中任何一个函数时,JNA不会抛出异常。当我调用GetDeviceParameters
方法并打印出结构时,我看到其中大部分都填充了我认为是设备默认配置的数据。但是,当我使用刚刚从get调用返回的相同数据调用SetDeviceParameters
方法时,设备会返回错误,指出参数错误。
我如何知道我是否正确映射了结构?
本机:
typedef struct _DeviceParameters
{
BOOL bMICREnable;
UINT nMICRFont;
BOOL bMICRSaveSamples;
UINT nMICRSpaces;
char cRejectSymbol;
UINT nReserved;
BOOL bReserved;
IMAGE_PROPERTIES ImagePropertiesFront1;
IMAGE_PROPERTIES ImagePropertiesFront2;
IMAGE_PROPERTIES ImagePropertiesRear1;
IMAGE_PROPERTIES ImagePropertiesRear2;
SNIPPET_PROPERTIES SnippetProperties[10];
BOOL bPrintEnable;
BOOL bOneDoc;
UINT nFeedingMode;
} DeviceParameters;
typedef struct _SnippetProperties
{
BOOL Enable;
BOOL Front;
Snippet Properties;
} SNIPPET_PROPERTIES;
typedef struct _Snippet
{
UINT Xposition;
UINT Yposition;
UINT Width;
UINT Height;
UINT Orientation;
UINT Color;
UINT Compression;
BOOL Millimeters;
} Snippet;
typedef struct _ImageProperties
{
UINT Format;
UINT Paging;
UINT Resolution;
UINT ColorDepth;
UINT Threshold;
} IMAGE_PROPERTIES;
爪哇:
public class DEVICE_PARAMETERS extends Structure {
public boolean bMICREnable;
public int nMICRFont;
public boolean bMICRSaveSamples;
public int nMICRSpaces;
public byte cRejectSymbol;
public int nReserved;
public boolean bReserved;
public IMAGE_PROPERTIES ImagePropertiesFront1;
public IMAGE_PROPERTIES ImagePropertiesFront2;
public IMAGE_PROPERTIES ImagePropertiesRear1;
public IMAGE_PROPERTIES ImagePropertiesRear2;
public SNIPPET_PROPERTIES[] SnippetProperties = new SNIPPET_PROPERTIES[10];
public boolean bPrintEnable;
public boolean bOneDoc;
public int nFeedingMode;
@Override
protected List getFieldOrder() {
return Arrays.asList(
"bMICREnable"
, "nMICRFont"
, "bMICRSaveSamples"
, "nMICRSpaces"
, "cRejectSymbol"
, "nReserved"
, "bReserved"
, "ImagePropertiesFront1"
, "ImagePropertiesFront2"
, "ImagePropertiesRear1"
, "ImagePropertiesRear2"
, "SnippetProperties"
, "bPrintEnable"
, "bOneDoc"
, "nFeedingMode"
);
}
}
public class IMAGE_PROPERTIES extends Structure {
public int Format;
public int Paging;
public int Resolution;
public int ColorDepth;
public int Threshold;
@SuppressWarnings("RedundantArrayCreation")
@Override
protected List getFieldOrder() {
return Arrays.asList(
new String[]{
"Format"
, "Paging"
, "Resolution"
, "ColorDepth"
, "Threshold"
}
);
}
}
public class SNIPPET_PROPERTIES extends Structure {
public boolean Enable;
public boolean Front;
public SNIPPET Properties = new SNIPPET();
@Override
protected List getFieldOrder() {
return Arrays.asList("Enable", "Front", "Properties");
}
}
public class SNIPPET extends Structure {
public int Xposition;
public int Yposition;
public int Width;
public int Height;
public int Orientation;
public int Color;
public int Compression;
public boolean Millimeters;
@Override
protected List getFieldOrder() {
return Arrays.asList("Xposition"
, "Yposition"
, "Width"
, "Height"
, "Orientation"
, "Color"
, "Compression"
, "Millimeters"
);
}
}
输出:
DEVICE_PARAMETERS(auto-allocated@0x16a25938 (520 bytes)) {
boolean bMICREnable@0=false
int nMICRFont@4=1
boolean bMICRSaveSamples@8=false
int nMICRSpaces@c=2
byte cRejectSymbol@10=3f
int nReserved@14=0
boolean bReserved@18=false
IMAGE_PROPERTIES ImagePropertiesFront1@1c=IMAGE_PROPERTIES(allocated@0x16a25954 (20 bytes) (shared from auto-allocated@0x16a25938 (520 bytes))) {
int Format@0=0
int Paging@4=0
int Resolution@8=0
int ColorDepth@c=0
int Threshold@10=0
}
IMAGE_PROPERTIES ImagePropertiesFront2@30=IMAGE_PROPERTIES(allocated@0x16a25968 (20 bytes) (shared from auto-allocated@0x16a25938 (520 bytes))) {
int Format@0=0
int Paging@4=0
int Resolution@8=0
int ColorDepth@c=0
int Threshold@10=0
}
IMAGE_PROPERTIES ImagePropertiesRear1@44=IMAGE_PROPERTIES(allocated@0x16a2597c (20 bytes) (shared from auto-allocated@0x16a25938 (520 bytes))) {
int Format@0=0
int Paging@4=0
int Resolution@8=0
int ColorDepth@c=0
int Threshold@10=0
}
IMAGE_PROPERTIES ImagePropertiesRear2@58=IMAGE_PROPERTIES(allocated@0x16a25990 (20 bytes) (shared from auto-allocated@0x16a25938 (520 bytes))) {
int Format@0=0
int Paging@4=0
int Resolution@8=0
int ColorDepth@c=0
int Threshold@10=0
}
SNIPPET_PROPERTIES SnippetProperties[10]@6c=[Lpanini.data.SNIPPET_PROPERTIES;@fb642f
boolean bPrintEnable@1fc=false
boolean bOneDoc@200=false
int nFeedingMode@204=1
}
memory dump
[00000000]
[01000000]
[00000000]
[02000000]
[3f000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[01000000]
Device Error: Wrong device parameters <-- this is where I try to set params
答案 0 :(得分:1)
你没有包含你的方法声明,它应该是这样的(假设你没有简单地在声明中输入错误):
boolean SetDeviceParameters(int deviceID, DeviceParameters.ByValue params);
boolean GetDeviceParameters(int deviceID, DeviceParameters params);
确保在传递给Structure.ByValue
方法时使用标记为SetDeviceParameters()
的结构版本。您需要定义结构的ByValue
版本。
public class DeviceParameters extends Structure {
public ByValue extends DeviceParameters implements Structure.ByValue {
public ByValue() { }
public ByValue(Pointer p) { super(p); read(); }
}
}
然后,您可以将struct *
转换为struct
,如下所示:
DeviceParameters dp = new DeviceParameters();
DeviceParameters.ByValue bv = new DeviceParameters.ByValue(dp.getPointer());