Java JNA:Can';t创建结构子类的对象-结构字段无效
我正在将C类型定义映射到JNA结构。如果C类型定义为:Java JNA:Can';t创建结构子类的对象-结构字段无效,java,jna,Java,Jna,我正在将C类型定义映射到JNA结构。如果C类型定义为: typedef struct _GLYCOUNTERS { unsigned int ulArraySize; LPGLYCOUNTER lpCounters; }GLYCOUNTERS, *LPGLYCOUNTERS; 这是我的JNA结构子类: public class GlyCounters extends Structure{ public class ByReference extends GlyCounters impl
typedef struct _GLYCOUNTERS {
unsigned int ulArraySize;
LPGLYCOUNTER lpCounters;
}GLYCOUNTERS, *LPGLYCOUNTERS;
这是我的JNA结构子类:
public class GlyCounters extends Structure{
public class ByReference extends GlyCounters implements Structure.ByReference {};
public class ByValue extends GlyCounters implements Structure.ByValue {};
public int ulArraySize;
public GlyCounter lpCounters;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "ulArraySize", "lpCounters"});
}
}
如您所见,我正在另一个类中创建对象,而GlyCounters是另一个类的嵌套类
这是我收到的错误消息:
Exception in thread "main" java.lang.IllegalArgumentException: Invalid Structure field in class btc_dll.GloryTypeDef$GlyCounters, field name 'lpCounters' (class btc_dll.GloryTypeDef$GlyCounter): Can't instantiate class btc_dll.GloryTypeDef$GlyCounter (java.lang.InstantiationException: btc_dll.GloryTypeDef$GlyCounter)
at com.sun.jna.Structure.validateField(Structure.java:1038)
at com.sun.jna.Structure.validateFields(Structure.java:1048)
at com.sun.jna.Structure.<init>(Structure.java:179)
at com.sun.jna.Structure.<init>(Structure.java:172)
at com.sun.jna.Structure.<init>(Structure.java:159)
at com.sun.jna.Structure.<init>(Structure.java:151)
at btc_dll.GloryTypeDef$GlyCounters.<init>(GloryTypeDef.java:298)
at btc_gui.Btc_gui.main(Btc_gui.java:54)
Java Result: 1
线程“main”java.lang.IllegalArgumentException中的异常:类btc_dll.GloryTypeDef$GlyCounters中的结构字段无效,字段名为“lpCounters”(类btc_dll.GloryTypeDef$GlyCounter):无法实例化类btc_dll.GloryTypeDef$GlyCounter(java.lang.InstantiationException:btc_dll.GloryTypeDef$GlyCounter)
位于com.sun.jna.Structure.validateField(Structure.java:1038)
位于com.sun.jna.Structure.validateFields(Structure.java:1048)
位于com.sun.jna.Structure.(Structure.java:179)
位于com.sun.jna.Structure.(Structure.java:172)
位于com.sun.jna.Structure.(Structure.java:159)
位于com.sun.jna.Structure.(Structure.java:151)
在btc_dll.GloryTypeDef$GlyCounters(GloryTypeDef.java:298)
位于btc_gui.btc_gui.main(btc_gui.java:54)
Java结果:1
导致问题的字段是另一个c typedef结构的另一个JNA结构类。在谷歌搜索错误消息后,我尝试不向这两个类添加参数构造函数,但错误仍然存在
有人遇到过类似的问题吗?当您希望在结构中使用类型为
struct*
的字段时,需要使用带有接口结构标记的结构。通过引用
已编辑
最常见的方法是:
public class GlyCounter extends Structure {
public class ByReference extends GlyCounter implements Structure.ByReference {};
// More definition here...
}
public class GlyCounters extends Structure{
public int ulArraySize;
public GlyCounter.ByReference lpCounters;
public GlyCounters(Pointer p) {
super(p);
read();
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "ulArraySize", "lpCounters"});
}
}
// To obtain the full array (assuming they're allocated as a block)
GlyCounters gc = new GlyCounters(pointer);
GlyCounter[] counters = gc.lpCounters.toArray(gc.ulArraySize());
公共类GlyCounter扩展结构{
公共类ByReference扩展了GlyCounter实现结构。ByReference{};
//这里有更多的定义。。。
}
公共类GlyCounters扩展结构{
公共综合治理;
公共GlyCounter.ByReference lpCounters;
公共计数器(指针p){
超级(p);
read();
}
@凌驾
受保护列表getFieldOrder(){
返回Arrays.asList(新字符串[]{“ulArraySize”,“lpCounters”});
}
}
//获取完整数组(假设它们被分配为块)
GlyCounters gc=新GlyCounters(指针);
GlyCounter[]counters=gc.lpCounters.toArray(gc.ulArraySize());
字段lpCounters
现在是指针类型,而不是内联的(即共享封闭结构的内存)。我不明白这如何适用于当前问题。据我所知,导致问题的字段是一个struct,而不是struct*。我已经尽我所能实现了你的建议,但是我仍然得到了编译错误。您能详细说明一下吗?字段的名称及其类型,“lpCounters”和lpglounter
,意味着它是指针类型。此代码不会在Netbeans中抛出错误,但它确实需要为ByReference和ByValue字段添加构造函数。IDE使用paramater指针p生成构造函数,并使用参数调用super。你能告诉我这是否足以达到我描述的目的吗?为了清楚起见,我省略了构造函数。通常,基于指针的构造函数和无参数的构造函数就足够了。大多数基于指针
的构造函数应该与为GlyCounters
提供的构造函数类似。我仍然对项目的这一部分存在问题。在您的示例中,在实例化类时,您为GlyCounters分配了一个指针。它来自哪里?我必须将这个struct-to-java方法映射到一个c函数,并将数据写入其中,但我没有得到任何合理的回报。
public class GlyCounter extends Structure {
public class ByReference extends GlyCounter implements Structure.ByReference {};
// More definition here...
}
public class GlyCounters extends Structure{
public int ulArraySize;
public GlyCounter.ByReference lpCounters;
public GlyCounters(Pointer p) {
super(p);
read();
}
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "ulArraySize", "lpCounters"});
}
}
// To obtain the full array (assuming they're allocated as a block)
GlyCounters gc = new GlyCounters(pointer);
GlyCounter[] counters = gc.lpCounters.toArray(gc.ulArraySize());