当前位置: 首页 > 知识库问答 >
问题:

JNA从DLL调用C++对象-java.lang.IllegalArgumentException:结构类的大小未知或为零

仲法
2023-03-14

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

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

线程“main”java.lang.IllegalArgumentException:结构类edu.nyu.cpptest.cpplib.cpplibdemo$cpplib$imyClass的大小未知或为零(确保所有字段都是公共的)com.sun.jna.Structure.deriveLayout(Structure.java:1374)com.sun.jna.Structure.CalculateSize(Structure.java:1158)com.sun.jna.Structure.CalculateSize(Structure.java:1110)

C++代码:

MyClass.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();
};

MyClass.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++代码中将'value'-field'从MyClass移到它的父IMyClass中,并在Java代码中声明IMyClass中的value-field。在这种情况下,我也有例外:

线程“main”java.lang.error:类edu.nyu.cpptest.cpplib.cpplibdemo$cpplib$imyClass上的structure.getFields(structure.java:1088)返回的名称([])与声明的字段名([value])不匹配。

我用简单的控制台应用程序测试了这一点,它在Vioprome Studio中加载了我的DLL,并且工作良好。而且我还可以通过JNI调用我的DLL,使用SWIG Java&DLL-wrapper Generation。这是有趣的,如果这是可能的与JNA。

共有1个答案

叶允晨
2023-03-14

Java结构需要具有与本机结构匹配的公共字段,并且需要以正确的顺序声明这些字段。通常,您的Java代码会有一个这样的注释:

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

    // rest of the implementation...
}
 类似资料:
  • 本文向大家介绍你真的知道C++对象大小吗?,包括了你真的知道C++对象大小吗?的使用技巧和注意事项,需要的朋友参考一下 我们都直到char大小为1,int为4,那么C++中对象的大小是多少呢? 看三个问题: C++中函数占不占对象的大小 空类的大小是多少? 如果类中有虚函数,类的大小是多少? 一,C++中函数占不占对象的大小 看一段代码: 可以看出,类的大小即为类的属性a的大小为4,函数并不占对象

  • 问题内容: 我正在将Java用于小型应用程序。这是对现有MFC项目的重写。我需要更改一个现有的dll,以启用使用JNI从Java进行的访问。所有这些Java知识对我来说都是新手,因此当我阅读其他论坛帖子时遇到了一些麻烦,并且感觉比较密集。在现有的dll中,我具有如下功能: 愚蠢的提问时间。如何正确设置它以被Java调用? 我尝试了这个: 我包括jni.h,一切编译正常。但是,当我从Java调用它时

  • 问题内容: 您好Go Lang和C#专家, 美好的一天。我想问你们是否有人尝试过Go程序调用C#DLL函数(类库类型)? 我进行了一些初步研究,并看到了以下文章: 但是这些都是从C Win32实现中创建的DLL。我尝试搜索加载到Go程序中的C#DLL,所有这些都会告诉您在Go程序上调用它之前,您需要具有C ++ / C(Win32)包装器。 另外,上面的链接将告诉您Go认为我认为是“ C”声明(类

  • 线程“main”java.lang.UnsatifiedLinkError:查找函数“StartConector”时出错:找不到指定的过程。在com.sun.jna.function.(function.java:179)在com.sun.jna.nativelibrary.getfunction(nativelibrary.java:350)在com.sun.jna.nativelibrary.

  • 我有一个测试车, 而applicatin.xml是 但它报告异常 java.lang.IllegalArgumentException:未知实体:com.chinalbs.entity.conductor(位于org.hibernate.ejb.abstractentyManagerImpl.persist(abstractentyManagerImpl.java:842)(位于sun.refle