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.
精彩评论