включая файлы классов динамически - PullRequest
4 голосов
/ 05 октября 2011

Сейчас я работаю над переносом Slim-сервера Fitnesse с java на Qt, что требует от меня возможности загружать классы, которые еще не существуют.

Я уже узнал, каксоздать экземпляр еще неизвестного класса здесь: Как я могу получить QMetaObject только из имени класса? Но для этого мне нужен уже включенный файл class.h, верно?

Так что я подумал об этомс плагинами.Я сделаю один интерфейсный класс и загрузлю необходимые файлы классов в виде DLL-файлов.Просто кажется, что нужно немного поработать, чтобы включить файлы классов.Есть ли более простой способ сделать это?

РЕДАКТИРОВАТЬ: я пытался сделать это с плагинами сейчас, и он не работает.Проблема заключается в следующем:
В моем интерфейсе я должен назвать методы, например, "setAttribute".
Но мой плагин должен иметь имена методов, такие как "setNumerator".
Так что я не могусопоставьте мой плагин с моим интерфейсом.Что заставляет меня задуматься, есть ли способ включить мой плагин без предварительного объявления интерфейса.Есть идеи?

1 Ответ

1 голос
/ 06 октября 2011

Я наконец-то нашел решение, которое - после нескольких часов неприятностей - теперь работает.

Класс QLibrary позволяет динамически загружать .dll-файлы, поэтому все, что мне нужно было сделать, это поместить свой класс в .dll и добавить функцию, которая возвращает указатель на требуемый класс.

это заголовочный файл .dll:

#ifndef DIVFIXTURE_H
#define DIVFIXTURE_H

#include<QObject>
#include<QVariant>

class __declspec(dllexport) DivFixture : public QObject
{
    Q_OBJECT
public:
    Q_INVOKABLE DivFixture();
    Q_INVOKABLE void setNumerator(QVariant num);
    Q_INVOKABLE void setDenominator(QVariant denom);
    Q_INVOKABLE QVariant quotient();

private:
    double numerator, denominator;
};

#endif

Это cpp-файл .dll:

#include "testfixture.h"

DivFixture::DivFixture(){}


extern "C" __declspec(dllexport) void DivFixture::setNumerator(QVariant num)
{
    numerator=num.toDouble();
}

extern "C" __declspec(dllexport) void DivFixture::setDenominator(QVariant denom)
{
    denominator=denom.toDouble();
}

extern "C" __declspec(dllexport) QVariant DivFixture::quotient()
{
    QVariant ret;
    ret=numerator/denominator;
    return ret;
}


//non-class function to return pointer to class
extern "C" __declspec(dllexport) DivFixture* create()
{
   return new DivFixture();
}

и вот как я загружаю свой класс:

currentFixture.setFileName("C:\\somepath\\testFixture.dll");
    if(currentFixture.load());
    {
        typedef QObject* (*getCurrentFixture)();
        getCurrentFixture fixture=(getCurrentFixture)currentFixture.resolve("create");
        if (fixture)
        {
            Fixture=fixture();
        }
    }

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...