[英]How do I pass a Structure that contains an array of Structures to a C++ function using JNA?
I am building a Java application that communicates with a particular manufacturer's API using JNA. 我正在构建一个使用JNA与特定制造商的API通信的Java应用程序。 I have a ton of function calls mapped and already working, but there are a pair of functions that have been giving me some grief.
我有大量的函数调用已映射,并且已经可以正常工作,但是有一对函数让我有些难过。
Both of these functions pass a data structure back and forth to configure the device. 这两个功能都来回传递数据结构以配置设备。 This structure has a nested array of data structures within it.
此结构中具有嵌套的数据结构数组。
The native definitions: 本机定义:
VISION_API_DECL BOOL VISION_API SetDeviceParameters( DWORD DeviceID, DeviceParameters DeviceParam );
VISION_API_DECL BOOL VISION_API GetDeviceParameters( DWORD DeviceID, DeviceParameters *DeviceParam );
I have them declared in Java like so: 我用Java这样声明它们:
public interface Driver extends Library {
...
public boolean SetDeviceParameters(int DeviceID, DEVICE_PARAMETERS DeviceParam);
public boolean GetDeviceParameters(int DeviceID, DEVICE_PARAMETERS DeviceParam);
...
}
These function calls seem to work. 这些函数调用似乎有效。 JNA does not throw an exception when I call either of those functions.
当我调用这些函数中的任何一个时,JNA都不会引发异常。 When I call the
GetDeviceParameters
method and print out the struct, I see most of it filled with data from what I would assume is the device's default configuration. 当我调用
GetDeviceParameters
方法并打印出该结构时,我看到其中大部分填充了我认为是设备默认配置的数据。 However, when I call the SetDeviceParameters
method using the same data just returned from the get call , the device returns an error saying the parameters are wrong. 但是,当我使用与get调用刚返回的相同数据来调用
SetDeviceParameters
方法时,设备将返回错误,指出参数错误。
How do I know if I have mapped the structure correctly? 我如何知道是否正确映射了结构?
Native: 本机:
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;
Java: Java的:
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"
);
}
}
Output: 输出:
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
You haven't included your method declarations, which should look like this (assuming you haven't simply made a typo in the declaration): 您尚未包括方法声明,该声明应如下所示(假设您未在声明中简单地打错字):
boolean SetDeviceParameters(int deviceID, DeviceParameters.ByValue params);
boolean GetDeviceParameters(int deviceID, DeviceParameters params);
Make sure that you use a version of the structure tagged with Structure.ByValue
when passing to the SetDeviceParameters()
method. 传递给
SetDeviceParameters()
方法时,请确保使用带有Structure.ByValue
标记的结构的版本。 You'll need to define a ByValue
version of your structure. 您需要定义结构的
ByValue
版本。
public class DeviceParameters extends Structure {
public ByValue extends DeviceParameters implements Structure.ByValue {
public ByValue() { }
public ByValue(Pointer p) { super(p); read(); }
}
}
You can then convert from struct *
to struct
like this: 然后,您可以从转换
struct *
到struct
是这样的:
DeviceParameters dp = new DeviceParameters();
DeviceParameters.ByValue bv = new DeviceParameters.ByValue(dp.getPointer());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.