gpt4 book ai didi

java - 如何使用 JNA 将包含结构数组的结构传递给 C++ 函数?

转载 作者:行者123 更新时间:2023-12-01 11:42:40 26 4
gpt4 key购买 nike

我正在构建一个 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 方法时,设备会返回一个错误,指出参数错误。

我如何知道我是否正确映射了结构?

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:

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

最佳答案

您还没有包含方法声明,它应该如下所示(假设您没有在声明中简单地输入错误):

boolean SetDeviceParameters(int deviceID, DeviceParameters.ByValue params);
boolean GetDeviceParameters(int deviceID, DeviceParameters params);

确保在传递给 SetDeviceParameters() 方法时使用标记有 Structure.ByValue 的结构版本。您需要定义结构的 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());

关于java - 如何使用 JNA 将包含结构数组的结构传递给 C++ 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29402840/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com