gpt4 book ai didi

java - JNA 从 DLL 调用 C++ 对象 - java.lang.IllegalArgumentException : Structure class has unknown or zero size

转载 作者:行者123 更新时间:2023-11-28 04:26:02 28 4
gpt4 key购买 nike

我正在尝试使用 JNA 访问我用 C++(Windows 32 位、Java 8、JNA 5.2.0、Visual Studio 2017 C++)编写的简单 DLL。 DLL 具有创建对象的功能。我想获取对象指针并访问 JAVA 代码中的对象函数。
我收到指向 native 对象的 JNA 指针并尝试初始化它的 Java 结构实现。
在这里我在 JNA-Structure 初始化期间有异常:

    public IMyClass(Pointer p) { 
super(p);

Exception in thread "main" java.lang.IllegalArgumentException: Structure class edu.nyu.cpptest.cpplib.CppLibDemo$CppLib$IMyClass has unknown or zero size (ensure all fields are public) at com.sun.jna.Structure.deriveLayout(Structure.java:1374) at com.sun.jna.Structure.calculateSize(Structure.java:1158) at com.sun.jna.Structure.calculateSize(Structure.java:1110) at com.sun.jna.Structure.useMemory(Structure.java:350) at com.sun.jna.Structure.(Structure.java:202) at com.sun.jna.Structure.(Structure.java:193) at com.sun.jna.Structure.(Structure.java:189) at edu.nyu.cpptest.cpplib.CppLibDemo$CppLib$IMyClass.(CppLibDemo.java:30) at edu.nyu.cpptest.cpplib.CppLibDemo.(CppLibDemo.java:52)

C++代码:

我的类.h:

class __declspec(dllexport) IMyClass {
public:
//int value;
virtual int getValue() = 0;
virtual void increment() = 0;
};

class MyClass : public IMyClass {
public:
int value;
MyClass();
MyClass(int v);
int getValue();
void increment();
};

extern "C"
{
__declspec(dllexport) IMyClass* createMyClass();
};

我的类.cpp:

MyClass::MyClass() {this->value = 0;}
MyClass::MyClass(int v) { this->value = v; }
int MyClass::getValue() { return value; }
void MyClass::increment() { value++; }

cpplib.cpp

extern "C" __declspec(dllexport) IMyClass* createMyClass() {
MyClass *mcl = new MyClass(0);
return mcl;
}

Java代码:

public class CppLibDemo {
public interface CppLib extends StdCallLibrary {
CppLib INSTANCE = Native.loadLibrary("cpplib.dll", CppLib.class);
Pointer createMyClass();
class IMyClass extends Structure {
interface Increment extends Callback {
public void invoke();
}
interface GetValue extends Callback {
public int invoke();
}
public IMyClass() { }
public IMyClass(Pointer p) {
super(p);
super.read();
}
Increment increment;
GetValue getValue;
//public int value;//I tried to add 'value' field in IMyClass-native and java code
//public void read() {
// value = (int)readField("value");
// super.read();
//}
}
}
CppLib.IMyClass myClass;
public CppLibDemo() {
Pointer ptr = CppLib.INSTANCE.createMyClass();
myClass = new CppLib.IMyClass(ptr);
}
public int getValue() {
return myClass.getValue.invoke();
}
public void increment() {
myClass.increment.invoke();
}
}

我还尝试在 C++ 代码中将“值”字段从 MyClass 移动到它的父级 IMyClass,并在 Java 代码中在 IMyClass 中声明值字段。在这种情况下,我也有异常(exception):

Exception in thread "main" java.lang.Error: Structure.getFieldOrder() on class edu.nyu.cpptest.cpplib.CppLibDemo$CppLib$IMyClass returns names ([]) which do not match declared field names ([value]) at com.sun.jna.Structure.getFields(Structure.java:1088) at com.sun.jna.Structure.deriveLayout(Structure.java:1233) at com.sun.jna.Structure.calculateSize(Structure.java:1158) at com.sun.jna.Structure.useMemory(Structure.java:350) at com.sun.jna.Structure.(Structure.java:202) at com.sun.jna.Structure.(Structure.java:193) at com.sun.jna.Structure.(Structure.java:189) at edu.nyu.cpptest.cpplib.CppLibDemo$CppLib$IMyClass.(CppLibDemo.java:30)

我使用简单的控制台应用程序对此进行了测试,它在 Viusual Studio 中加载了我的 DLL,并且运行良好。我还可以使用 SWIG java 和 DLL 包装器生成通过 JNI 调用我的 DLL。这很有趣,如果 JNA 可以做到这一点。

最佳答案

Java 结构需要具有与 native 结构匹配的公共(public)字段,并且需要以正确的顺序声明这些字段。通常,您的 Java 代码会有一个注解来执行此操作:

@Structure.FieldOrder({"value"})
public class ExampleStruct extends Structure {
public int value;

// rest of the implementation...
}

关于java - JNA 从 DLL 调用 C++ 对象 - java.lang.IllegalArgumentException : Structure class has unknown or zero size,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54298174/

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