Qt QPluginLoader.instance()-它实际上是如何工作的?
我目前正在从事一个以动态插件加载为中心的Qt项目。我正在使用Qt的QPluginLoader加载DLL。通过CameraPluginStructs访问不同的插件,定义如下:Qt QPluginLoader.instance()-它实际上是如何工作的?,qt,dll,constructor,Qt,Dll,Constructor,我目前正在从事一个以动态插件加载为中心的Qt项目。我正在使用Qt的QPluginLoader加载DLL。通过CameraPluginStructs访问不同的插件,定义如下: struct CameraPluginStruct { QString name; QString filePath; CameraPluginInterface* plugin; QPluginLoader* pluginLoader; CameraPluginStruct(QSt
struct CameraPluginStruct
{
QString name;
QString filePath;
CameraPluginInterface* plugin;
QPluginLoader* pluginLoader;
CameraPluginStruct(QString filePath=nullptr, QString name=nullptr):
filePath(filepath), name(name), plugin(nullptr), pluginLoader(nullptr){}
};
要加载插件,将调用以下函数:
void loadPlugin(CameraPluginStruct& p)
{
p.pluginLoader = new QPluginLoader(p.filePath);
p.pluginLoader->load();
QObject* possiblePlugin = p.pluginLoader->instance(); //QPluginLoader.instance();
if(possiblePlugin)
{
// cast from QObject to correct type:
p.plugin = qobjectcast<CameraPluginInterface>(possiblePlugin);
}
}
我制作了一些简单的测试插件,在调用构造函数时将消息写入控制台。为简单起见,假设我有两个测试插件,DLL A和DLL B。当我使用loadPlugin()函数加载A时,将调用插件中的构造函数,并在控制台中写入相应的消息。我可以用B做同样的事情,一切似乎都正常——B的构造函数消息被写入控制台,其他函数也正常工作
现在,当我尝试创建另一个连接到A或B的CameraPluginStruct时,问题出现了。没有消息写入控制台,这使我认为构造函数没有被调用。尽管如此,我还是能够成功地调用插件中的其他测试函数(DoSomething(),见下文)。如果卸载连接到A或B的所有CameraPlugins,然后再次加载DLL,则在第一次加载时会再次调用构造函数
QPluginLoader.instance()调用在文档中描述如下:
“返回插件的根组件对象。(…)该组件对象是一个QObject。使用QObject_cast()访问您需要的接口。”
对……感兴趣。”
那么,每次调用DLL中的构造函数,而不仅仅是第一次调用,不是很自然吗
据我所知,DLL对于任何程序只加载一次。因此,我也尝试了在每个DLL文件中只使用一个QPluginLoader,得到了相同的结果。Qt还说:
“QPluginLoader的多个实例可用于访问同一物理插件。”
因此,无论如何,我看不出这是问题的根源
如果有人能澄清QPluginLoader.instance()是如何工作的,我将不胜感激。为什么构造函数(至少看起来是这样)只在我第一次使用instance()调用时才被调用
谢谢大家!
以下是DLL中的代码(输出文本在A和B中有所不同):
TestDLL::TestDLL()
{
std::cout加载插件时(即第一次调用QPluginLoader::instance()
),将创建它的单个实例-这是您的根实例。根实例是QPluginLoader
将为您创建的唯一实例
如果需要更多,则创建一个createInstance()
或clone()
方法,以便可以从根实例创建新实例。或者更传统地,将插件类设置为要公开的类类型的工厂。这是一个旧线程,但我仍然注意到,您使用的qobject\u cast
并不完全正确。无论何时使用qobject\u cast
,dynamic\u cast
等。您应该始终检查该强制转换的结果。如果强制转换失败,则返回0。在您的情况下,您有possiblePlugin
,在我看来,如果它不等于0,您认为您肯定有您类型的插件,这可能并不总是如此。
void unloadPlugin(CameraPluginStruct& p)
{
p.pluginLoader->unload(); // QPluginLoader.unload();
p.pluginLoader->~QPluginLoader();
p.pluginLoader = nullptr;
p.plugin = nullptr;
}
TestDLL::TestDLL()
{
std::cout << "This is written from the constructor in A \n";
}
QString TestDLL::Name() const
{
return "Hello, writing from Name() \n";
}
void TestDLL::DoSomething() const
{
qDebug() << "Hello, this text comes from DoSomething()"\n;
}