用qt返回指向指针jna的对象



我正在做一个JNA项目:

    其他的是用c++ (QT)编写的。
  • 一个CPP文件正在链接JAVA和c++。

JAVA项目使用JNA 3.0.9版本:
http://mvnrepository.com/artifact/com.sun.jna/jna/3.0.9

我在Windows 8上使用QT 5.2和JAVA 1.7。我从qt文件夹复制qt dll到我的JAVA项目,以便应用程序可以工作。我不知道如何,在JAVA方法中,我从属于dll的方法中获得返回对象。我看到了关于指针的文档,但是我没有找到从dll中开发的方法获取对象的合适类型。

我的qt项目文件:

#-------------------------------------------------
#
# Project created by QtCreator 2014-05-17T21:25:07
#
#-------------------------------------------------
QT       -= gui
TARGET = composite
TEMPLATE = lib
SOURCES += classes/my_component_class.cpp
        classes/my_composite_class.cpp
        wrapper.cpp
HEADERS += classes/my_component_class.h
        classes/my_composite_class.h

类/my_component_class.h:

#ifndef MY_COMPONENT_CLASS_H
#define MY_COMPONENT_CLASS_H
class MyComponentClass {
private:
    int myFirstField;
    int mySecondField;
public:
    MyComponentClass();
    MyComponentClass(int,int);
    void setMyFirstField(const int&);
    void setMySecondField(const int&);
    const int& getMyFirstField() const;
    const int& getMySecondField() const;
};
#endif

类/my_component_class.cpp:

#include "classes/my_component_class.h"
MyComponentClass::MyComponentClass(){
    myFirstField = 0;
    mySecondField = 0;
}
MyComponentClass::MyComponentClass(int _myFirstField,int _mySecondField){
    setMyFirstField(_myFirstField);
    setMySecondField(_mySecondField);
}
void MyComponentClass::setMyFirstField(const int& _myFirstField) {
    myFirstField = _myFirstField;
}
void MyComponentClass::setMySecondField(const int& _mySecondField) {
    mySecondField = _mySecondField;
}
const int& MyComponentClass::getMyFirstField() const{
    return myFirstField;
}
const int& MyComponentClass::getMySecondField() const{
    return mySecondField;
}

类/my_composite_class.h:

#ifndef MY_COMPOSITE_CLASS_H
#define MY_COMPOSITE_CLASS_H
#include <QList>
#include "classes/my_component_class.h"
class MyCompositeClass {
private:
    QList<MyComponentClass> list;
public:
    MyCompositeClass();
    void setList(const QList<MyComponentClass>&);
    const QList<MyComponentClass>& getList() const;
    QList<MyComponentClass>& refList();
};
#endif

类/my_composite_class.cpp:

#include "classes/my_composite_class.h"
MyCompositeClass::MyCompositeClass() {
    list << MyComponentClass(1,2);//Some objects are added to the list
    list << MyComponentClass(3,4);
}
void MyCompositeClass::setList(const QList<MyComponentClass>& _list) {
    list = _list;
}
const QList<MyComponentClass>& MyCompositeClass::getList() const{
    return list;
}
QList<MyComponentClass>& MyCompositeClass::refList() {
    return list;
}

wrapper.cpp:

#include "classes/my_composite_class.h"
extern "C"{
    static MyCompositeClass* composite = NULL;
    void create(){
        if(composite == NULL) {//Create once
            composite = new MyCompositeClass();
        }
    }
    void* list() {
        create();//Avoid segmentation fault
        //Does it exist an other way to get pointer from the returned list?
        return &(composite->refList());
    }

    void destroy(){
        if(composite != NULL){
            //Delete the instance only if there is a created instance
            delete composite;
            composite = NULL;
        }
    }
}

我在Windows 8上工作,所以输出dll是composite.dll

IComposite.java:

package mainPackage;
import com.sun.jna.Library;
import com.sun.jna.Native;
public interface IComposite extends Library{
    //Load dll once
    public IComposite INSTANCE = (IComposite) Native.loadLibrary("composite", IComposite.class);
    //usable methods in the JAVA code
    public void create();
    public void destroy();
    public Pointer list();
}

CompositeSample.java:

package mainPackage;
public class CompositeSample{
    public static void main(String[] args) {
        String path_ = CompositeSample.class.getProtectionDomain().getCodeSource().getLocation().getPath();
        if (path_.endsWith(".jar")) {
            //In order to treat executable jars, it is recommanded to change
            //the property of java.library.path
            System.setProperty("java.library.path", path_.substring(1)+"!/");
        }
        IComposite integerMath = IComposite.INSTANCE;
        integerMath.create();
        // What do I have to do with the returned pointer from the method "list" of the interface "IComposite"
        // in order to get the list from the returned pointer?
        integerMath.destroy();// free allocated memory
    }
}

感谢那些能帮助我的人。

我不是JNA的专业人员,所以这只是一个提示。我不认为它是可能神奇地得到包含在非基本类型的指针的值。在我看来,您应该在Java中为您的MyComponentClass创建一个映射类型。不幸的是,我不知道怎么做。

如果我是你,我会用最简单的方法;创建一个包含我的数据的结构体,并使用该结构体作为返回值,而不是返回整个类对象。

查看这个示例,了解如何映射一个结构体以及如何使用JNA发送/检索一个结构体数组http://www.eshayne.com/jnaex/example06.html

开箱外,Java对QList类型一无所知,因此您在Java代码中只将其视为不透明的指针。为了解决这个问题,你可以只公开一个普通的C API,或者提供一个Java Qt包装器。

看看Qt Jambi。它是Qt的Java绑定,允许您在Java中使用Qt类型。特别是,Jambi生成器将自动为您的c++代码生成Java包装器,并自动在Qt集合和Java集合之间进行转换。

最新更新