12

所以我有一个基于 QT API 的应用程序,它使用 QPlugin 系统。使用起来相当简单,您定义一个从接口继承的类,当插件加载时,您会得到该类的一个实例。最后,它会归结为dlopen/dlsymLoadLibrary/ GetProcAddress,任何适合操作系统的东西。我在这里没有问题,一切都按预期工作。

所以,正题。有很多功能涉及需要引用主应用程序提供的数据/功能的插件。例如,我的应用程序有一个 GUI,所以我的应用程序中有一个“ plugin::v1::gui”函数,它返回一个QWidget *. 如果我希望插件能够向我的 UI 添加内容,或者甚至让它的对话框成为我的 UI 的子级,它需要一个指向它的指针。

我开始在 Linux 上进行开发并很快遇到这样一个事实,即默认情况下,加载器不会用加载它的应用程序中的符号填充共享对象中的未解析符号。没问题,轻松解决。将“ -rdynamic”添加到我的标志并继续前进。事情运作良好。

现在我发现在 Windows 上似乎没有等价物:(。那么什么是好的解决方案?

到目前为止,我想出的最好的方法是在我的主应用程序中填充一个结构,该结构具有指向插件可能关心的每个对象/函数的指针。然后将其传递给插件的 " init()" 函数,现在它具有指向所有内容的正确指针,但这是一个烦人的解决方案,因为现在每当我添加某些内容时,我都必须在多个地方进行更改。

有更好的解决方案吗?SO 社区是如何处理这个问题的?

4

3 回答 3

4

为应用程序公开的主要交互对象创建一组接口,并将它们构建在自己的 lib/dll 中,并在应用程序中的类上适当地实现这些接口。该库还应该包含一个插件接口,其中可能只有一个插件对象将实现的“初始化”方法。

应用程序和插件显然将链接到该 DLL,一旦应用程序加载插件,应用程序应该调用插件的初始化方法,该方法将具有参数来接受控制应用程序所需的任何对象。

一种简化的流行方法是在应用程序中实现类似于 DOM 的层次结构,以便插件可以从一个根对象访问应用程序中的所有相关对象。

于 2008-12-09T22:42:57.817 回答
0

创建一个注册表对象,该对象在包含公开组件字典的初始化函数中传递给插件。然后允许插件通过该注册表中的字符串名称或其他标识符请求指向组件的指针。它为稳定的接口牺牲了编译时类型的安全性。

还有更多重量级的解决方案,例如CORBA ...

于 2008-12-09T03:40:11.007 回答
0

你以一种相对较好的方式做到了这一点。Helper-Classes 通常是(仅)插入新功能的纯粹方式。如果您新设计您的软件,您必须提到并非每个插件都应该访问您的管理结构。所以插件设计应该有区别。

一种可能性:创建一些您从中继承的抽象类,这些类具有将所需指针设置为 Widget 左右的功能。

其他可能性:使用 getParent().getMainWidget()、getParent().getConfigWidget() ... 的功能扩展您的主(父)类。


如果它只是从你的 UI-Plugin 动态加载 UI 而不使用指针,你可以按照这个页面上的描述来做: http: //dolzhenko.blogspot.com/2008/10/qt4-dynamic-loading-ui-from -other-ui_07.html

它是通过 ui-Files 完成的,您可以通过主配置文件或其他方式访问它。

于 2008-12-09T13:37:16.607 回答