我有一个我想讨论的概念问题。首先,我为插件加载创建了一个自动系统,其工作原理如下:
1)给出了插件文件名或路径。
2)然后可以使用接口指针进行查询,并在找到时将其插入适当的插件中(可选择使用其他条件)。
用于查找实现的模板化函数如下所示:
template<tInterface> tInterface *implementation(const Requirements &req = Requierements())
{
tInterface *interface = nullptr;
for(QPluginLoader *loader : loaders(req)) //returns list of plugins that meet requirements in req
{
interface = qobject_cast<tInterface*>(loader.instance())
if(interface)
break;
}
return interface;
}
根据Qt文档,插件instance()
(返回根组件)应该是#34;共享&#34;在同一文件上运行的所有QPluginLoader对象之间。好吧,我发现事实并非如此。当从插件构造函数(或在根节点调用的任何构造函数)中调用它时,上面的代码将无限循环。因为这样的调用将实例化相同的插件(以及其他插件)以测试将触发另一个调用的请求实现,等等。只有在插件构造函数外部调用时它才能正常工作......
我试图找出一个解决方案,允许我甚至在插件的构造函数中使用它。到目前为止,我无法想到一种方法或机制会阻止循环,因此我的问题在这里。谢谢你的任何想法!
答案 0 :(得分:0)
好的,答案很简单。当前名为instance()
的QPluginLoader对象必须被锁定&#34;在调用instance()
之前,以便在第一次调用完成之前禁止对其进行后续调用 - 这是一种互斥行为。这可以防止在同一个QPluginLoader上调用instance()
内部调用instance()
的问题(因为搜索所有插件寻找可能的接口实现,请参见OP执行此操作的函数)
我通过跟踪正在使用的QPluginLoader对象来完成它&#34;在instance()
完成后释放它们。这允许我在其他插件的构造函数中请求插件,唯一的限制是我不能请求相同的插件或任何&#34; parent&#34;加载层次结构中的插件:
如果插件X的构造函数请求插件Y(在其构造函数中)请求插件Z,则Z不能在其自己的构造函数中请求Y或X(并且Y不能请求X)。这样的尝试将无法返回nullptr接口。
为了完整起见,这里是修改后的功能:
template<tInterface> tInterface *implementation(const Requirements &req = Requierements())
{
tInterface *interface = nullptr;
for(QPluginLoader *loader : loaders(req))
//loaders() returns list of plugins that meet requirements in req
//AND ARE NOT PRESENT IN m_Locked
{
m_Locked << loader;
interface = qobject_cast<tInterface*>(loader.instance())
m_Locked.removeOne(loader);
if(interface)
break;
}
return interface;
}