新建一个QWidget项目,并定义一个插件接口类
testinterface.h
#pragma once
#include <QObject>
class TestInterface {
public:
TestInterface(){};
virtual ~TestInterface() {};
virtual void print() = 0;
};
//一定是唯一的标识符
#define TestInterface_iid "Examples.Plugin.TestInterface"
QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(TestInterface, TestInterface_iid)
QT_END_NAMESPACE
插件加载函数
bool Test::loadPlugin() {
QDir pluginsDir(qApp->applicationDirPath());
pluginsDir.cd("plugins");
QStringList names = pluginsDir.entryList(QDir::Files);
for (QString fileName : names) {
pluginLoader->setFileName(pluginsDir.absoluteFilePath(fileName));
qDebug() << pluginLoader->loadHints();
//pluginLoader->setLoadHints(QLibrary::PreventUnloadHint);
pluginLoader->setLoadHints(0);
qDebug() << pluginLoader->loadHints();
QObject* plugin = pluginLoader->instance();
if (plugin) {
testIn == nullptr ?
testIn = qobject_cast<TestInterface*>(plugin) : void();
testIn->print();
break;
}
else {
qWarning() << "插件加载错误:" + pluginLoader->errorString().toUtf8();
//return false;
}
}
QTimer::singleShot(300, this, [&]() {
bool stesa;
stesa = pluginLoader->isLoaded();//判断是否加载
stesa = pluginLoader->unload();//卸载
//testIn->print();
qWarning() << stesa;
});
return true;
}
以上代码只是测试加载和卸载
通过测试插件加载时默认的loadHints是PreventUnloadHint,即使卸载成功也无法删除插件,但是能改名称,如果想卸载后删除插件需要在instance()前调用pluginLoader->setLoadHints(0);
新建插件项目
将插件生成路径改到运行程序根目录的plugins文件下
代码如下
qtclasslibrary1.h
#pragma once
#include "qtclasslibrary1_global.h"
#include <QGenericPlugin>
#include "../test/testinterface.h"
class QTCLASSLIBRARY1_EXPORT QtClassLibrary1 :public QObject, public TestInterface {
Q_OBJECT
Q_INTERFACES(TestInterface)
Q_PLUGIN_METADATA(IID TestInterface_iid)
public:
QtClassLibrary1();
~QtClassLibrary1();
void print();//继承接口,并实现成员函数
};
qtclasslibrary1.cpp
#include "qtclasslibrary1.h"
QtClassLibrary1::QtClassLibrary1(){
}
QtClassLibrary1::~QtClassLibrary1() {
}
void QtClassLibrary1::print() {
qDebug() << "sjfkdjsfd";
}
总结:
1.多个插件可以使用同样的接口,插件会被重复的单独加载成一个实例。
2.插件加载时默认的loadHints是PreventUnloadHint,即使卸载成功也无法删除插件,但是能改名称,如果想卸载后删除插件需要调用pluginLoader->setLoadHints(0)
setLoadHints(0)出处;
3.一旦卸载成功,插件的所有引用将不能使用
若多个实例使用了相同的插件,则唯有当所有实例都调用 unload()时,函数才会返回true,插件才会被卸载,之前的实例在调用unload()时都会返回false