【发布时间】:2010-09-27 17:40:13
【问题描述】:
我正在做一个项目,我会发现一个基本的插件系统很有用。本质上,我创建了基类,并且可以将这个基类提供给插件开发人员。然后开发人员覆盖它并覆盖方法。然后这就是我有点不清楚的地方。它是如何从这里工作的?我在哪里可以找到与此类系统开发相关的文档?
谢谢
【问题讨论】:
我正在做一个项目,我会发现一个基本的插件系统很有用。本质上,我创建了基类,并且可以将这个基类提供给插件开发人员。然后开发人员覆盖它并覆盖方法。然后这就是我有点不清楚的地方。它是如何从这里工作的?我在哪里可以找到与此类系统开发相关的文档?
谢谢
【问题讨论】:
我所知道的插件系统都使用动态库。基本上,您需要在系统内核和插件之间定义一个小的、有效的握手。由于没有 C++ ABI,插件必须要么只使用 C API,要么使用与系统内核完全相同的编译器(可能还有编译器版本)。
最简单的协议是一个函数,所有插件开发者都必须提供它,它返回一个从你的基类派生的类的实例,返回一个基类指针。 (extern "C" 确保该函数不会有错误的名称,因此更容易通过其名称找到。)类似于:
extern "C" {
plugin_base* get_plugin();
}
然后内核会尝试将在指定位置找到的二进制文件加载为动态库,并尝试找到get_plugin() 函数。如果成功,它将调用此函数并以加载的插件实例结束。
当然,如果还具有检查插件编译所针对的 API 版本与内核版本的功能,那就太好了。 (毕竟,您可能会更改该基类。)您可能还有其他函数,它们返回有关插件的信息(或者您将其作为基类中的虚拟对象)。这在很大程度上取决于系统的性质。
【讨论】:
在 Linux 上,插件是一个共享库(带有 .so 扩展名),它提供一个或多个在插件 API 中命名的函数。您的程序使用dlopen 打开库并使用dlsym 获取指向函数的指针并使用指针调用函数。该插件可以调用从您的程序公开导出的任何函数。
【讨论】:
您可以将插件编译为动态/共享库,将其放入插件文件夹中,然后从您的代码中动态加载插件文件夹中的所有 dll 文件。
您可以查看 GIMP 等程序的源代码,了解它们是如何实现插件的。
【讨论】:
您能找到的几乎唯一文档将是现有系统。
基本上,您有两种常见的插件类型。一个处理诸如与某些外国文件类型之间的翻译之类的事情。在这种情况下,您通常具有大约三个功能:一是识别文件格式,一是读取,一是写入。除此之外,您通常还有一些字符串来指定文件扩展名。
另一种可能性是在您的程序内部进行处理。在这种情况下,它通常会指定一些要添加到菜单结构中的条目以及要为每个条目调用的函数。在大多数情况下,您将至少有一个其他功能来执行序列化其当前配置的操作。从那里开始,由您决定如何公开足够多的程序内部结构,以便它能够做一些有用的事情。
【讨论】: