Возвращает объект в указатель jna с qt

Я работаю над проектом JNA:

  • Некоторые файлы написаны в JAVA.
  • Другие из них написаны в C++ (QT).
  • Файл CPP связывает JAVA и C++.

В проекте JAVA используется версия 3.0.9 JNA: http://mvnrepository.com/artifact/com.sun.jna/jna/3.0.9

Я использую QT 5.2 и JAVA 1.7 в Windows 8. Я копиваю qt dll из qt в мой проект 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
</mycomponentclass></mycomponentclass></mycomponentclass></mycomponentclass></qlist>

Классы /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;
}
</mycomponentclass></mycomponentclass></mycomponentclass>

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 является составной.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
 }

}

Спасибо за людей, которые смогут мне помочь.

2 ответа

Я не профессионал в JNA, так что это всего лишь намек. Я не думаю, что можно магически получить значение, содержащееся в указателе не примитивного типа. На мой взгляд, вы должны создать тип отображения в Java для своего MyComponentClass. К сожалению, я не знаю, как это сделать.

Если бы я был вами, я бы сделал это легко; создайте структуру, которая будет содержать мои данные, и используйте эту структуру как возвращаемое значение вместо возврата всего объекта класса.

проверьте этот пример, чтобы увидеть, как сопоставить структуру и как отправить/получить массив структур, используя JNA http://www.eshayne.com/jnaex/example06.html


Из коробки Java ничего не знает о типе QList, поэтому вы видите его только как непрозрачный указатель в вашем Java-коде. Чтобы исправить это, вы можете либо открыть простой API C, либо предоставить оболочку Java Qt.

Посмотрите на Qt Jambi. Это привязка Java для Qt, которая позволит вам использовать типы Qt в Java. В частности, генератор Jambi автоматически генерирует оболочку Java для вашего кода C++ и автоматически конвертирует между коллекциями Qt и коллекциями Java.

licensed under cc by-sa 3.0 with attribution.