Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 插件API设计_C++_Api_Qt_Plugins_Dll - Fatal编程技术网

C++ 插件API设计

C++ 插件API设计,c++,api,qt,plugins,dll,C++,Api,Qt,Plugins,Dll,因此,我有一个应用程序,它在很大程度上基于使用QPlugin系统的QtaPI。它使用起来相当简单,您定义了一个从接口继承的类,当加载插件时,您会得到该类的一个实例。最后,它将归结为一个dlopen/dlsym或LoadLibrary/GetProcAddress,任何适合操作系统的东西。我在这里没有问题,一切正常 那么,这个问题。有很多功能需要插件引用主应用程序提供的数据/功能。例如,我的应用程序有一个GUI,所以我的应用程序中有一个“plugin::v1::GUI”函数,它返回一个QWidge

因此,我有一个应用程序,它在很大程度上基于使用QPlugin系统的QtaPI。它使用起来相当简单,您定义了一个从接口继承的类,当加载插件时,您会得到该类的一个实例。最后,它将归结为一个
dlopen
/
dlsym
LoadLibrary
/
GetProcAddress
,任何适合操作系统的东西。我在这里没有问题,一切正常

那么,这个问题。有很多功能需要插件引用主应用程序提供的数据/功能。例如,我的应用程序有一个GUI,所以我的应用程序中有一个“
plugin::v1::GUI
”函数,它返回一个
QWidget*
。如果我想要一个插件能够向我的用户界面添加东西,或者甚至使它的对话框成为我的用户界面的子项,那么它需要一个指向它的指针

我开始在Linux上开发,很快就遇到了这样一个事实:默认情况下,加载程序不会在共享对象中用加载它的应用程序中的符号填充未解析的符号。没问题,很容易解决。将“
-rdynamic
”添加到我的标志并继续。事情进展顺利

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

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


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

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


还有更多的重量级解决方案,如…

您已经以一种相对较好的方式完成了这项工作。 助手类通常是(仅)插入新功能的纯方法。 如果你刚开始设计你的软件,你必须提到不是每个插件都应该访问你的管理结构。 所以插件设计应该有所不同

一种可能性: 创建一些您从中继承的抽象类,这些抽象类具有设置所需的指向小部件的指针等功能

其他可能性: 使用getParent().getMainWidget()、getParent().getConfigWidget()等函数扩展主(父)类


如果只是从您的UI插件中动态加载UI,而不使用指针,您可以按照本页所述操作:


这是通过用户界面文件完成的,您可以通过主配置文件或其他任何方式访问这些文件。

为应用程序将公开的主要交互对象创建一组接口,并将它们构建在自己的lib/dll中,并根据需要在应用程序中的类上实现这些接口。库还应包括一个插件与插件对象将实现的“初始化”方法的接口

应用程序和插件显然将链接到该DLL,应用程序加载插件后,应用程序应调用插件的initialize方法,该方法将具有参数以接受控制应用程序所需的任何对象


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

这与我的“迄今为止我所想到的最好的…”基本相同唯一的区别是他们是通过结构元素还是通过字符串传递请求。由于类型安全性,我将采用结构。我无法想象这个问题的任何其他解决方案。您对Evan有何看法?不幸的是,到目前为止,我还没有发现任何真正优越的方法。Linux的-rdynamic真的会很好o坚持。我已经开始将我的插件API转换为已传递的结构,要正确操作确实很费时。下面是一篇很好的文章,详细解释了如何以这种方式实现插件: