开发者

including class-files dynamically

Right now I´m working on porting Fitnesse´s Slim-Server from java to Qt, which requires me to be able to load classes that don´t exist yet.

I already found out how to instantiate the yet unknown class here: How I can get QMetaObject from just class name? But for this I need the class.h file already included, right?

So I thought about doing it with plugins. I´ll do one interface-class and load the required class-files as .dll files. It just seems a 开发者_JAVA技巧little bit much work just to get the class files included. Is there an easier way to do it?

EDIT: I tried doing it with plugins now and it doesn´t work. The problem is as follows:

In my interface I have to name the methods, for example "setAttribute".

But my plugin needs to have method names like "setNumerator".

So I´m unable to match my plugin with my interface. Which leaves me wondering if there´s any way to include my plugin without having to declare an interface first. Any ideas?


I finally came up with a solution, which - after some hours of trouble - is now working.

The QLibrary class allows to load .dll-files dynamically, so all I had to do was putting my class into a .dll, and add a function, that returns a pointer to the required class.

this is the .dll´s header-file:

#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

this ist the .dll´s cpp-file:

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

and this is how I load my class:

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

After that I can get the QMetaObject and invoke any method I like. Hope this helps those who will face a similar problem in the future.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜