我正在研究JNA项目:
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 dll从qt文件夹复制到我的JAVA项目,以便应用程序可以工作。 我不知道如何在JAVA方法中从属于dll的方法中获取返回的对象。我看到了有关Pointer的文档,但是我没有找到适合从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
}
}
感谢能够帮助我的人们。
答案 0 :(得分:3)
我不是JNA的专业人士,所以这只是一个提示。
我认为不可能神奇地获取非基本类型指针中包含的值。在我看来,你应该在Java中为MyComponentClass
创建一个映射类型。不幸的是我不知道怎么做。
如果我是你,我会以简单的方式做到;创建一个包含我的数据的结构,并使用此结构作为返回值,而不是返回整个类对象。
检查此示例以了解如何映射结构以及如何使用JNA发送/检索结构数组 http://www.eshayne.com/jnaex/example06.html
答案 1 :(得分:2)
开箱即用,Java对QList类型一无所知,因此您只能将其视为Java代码中的不透明指针。要解决此问题,您可以只公开普通的C API,也可以提供Java Qt包装器。
看看Qt Jambi。它是Qt的Java绑定,可以让你在Java中使用Qt类型。具体来说,Jambi generator将自动为您的C ++代码生成Java包装器,并自动在Qt集合和Java集合之间进行转换。