【问题标题】:Hot-pluggable C++ library possible?可热插拔的 C++ 库可能吗?
【发布时间】:2010-06-23 16:45:56
【问题描述】:

我正在寻找“热插拔”C++ 代码库。我有兴趣让这种技术在 Linux/Mac/Windows 之间跨平台工作。基本上我想拥有定义所有可调用接口的主程序#include“StateMachine.h”。然后在运行时和 DURING EXECUTION 加载和卸载 StateMachineLibrary.a 以让我的应用程序使用不同的状态机。

我的一个想法可能是编写一个包装器,将编译后的代码加载到我自己的 malloc 内存中并在该内存中创建函数指针?

动机是我的项目的状态机部分会经常更改并需要重新编译,也将允许主应用程序在加载不同的状态机的情况下继续运行。由于某些问题,我希望使用“热插拔”库代替 Lua 脚本之类的东西,因此考虑到已经探索了替代方案。

【问题讨论】:

标签: c++ cross-platform shared-libraries dynamic-linking


【解决方案1】:

定义一个基本接口并从中派生出您的实现。将它们放入动态库 (DLL/SO) 并在运行时加载它们。该库只需要一个静态工厂函数即可向您提供其实现的实例。

// shared
class Base {
 public:
   virtual void DoTheWork() = 0;
};

// within the DLL/SO
class Hotplugged : public Base {
  public:
   virtual void DoTheWork() {
      std::cout<<"I got hotplugged!"<<std::endl;
   }
};

extern "C" Base* CreateIt() {
  return new Hotplugged();
} 

// within the app (sample for Windows/MSVC)
... ::LoadLibrary("mydll");
Base* (*fpCreateIt)() = (Base*(*)())::GetProcAddress(... "CreateIt");
// call the function pointer to obtain a Base instance
Base* mybase = fpCreateIt();

// prints the above text
mybase->DoTheWork(); 
delete mybase;

注意:这只是一个草图。它有一些缺陷,例如我忽略了所有权语义,如果我们刚刚加载的 DLL 与我们二进制兼容,则不会进行实际检查。考虑一下,或者寻找现有的实现(在其他回复中提到了一些)。

【讨论】:

    【解决方案2】:

    这是可能的。对于跨平台工作(至少只能重新编译),您可能需要查看一些现有的执行此操作的框架。

    OpenSceneGraph 包含用于加载和卸载插件的全功能“热插拔”实现。

    Qt has a plugin framework,以及。

    “诀窍”是为您的插件提供一个干净的界面,并且只使用可以加载和卸载的动态库。几乎每个平台(所有主要平台)都支持动态加载和卸载库,因此没有什么可以阻止它的工作。

    【讨论】:

      【解决方案3】:

      是的 - 这当然是可能的。在之前我们开发 3D 图形 API 和应用程序的角色中,我们让用户“即时”选择显示驱动程序。视图必须重新创建,但应用程序本身不需要关闭。

      【讨论】:

        【解决方案4】:

        虽然它的许多部分已经过时,Advanced C++ Programming Styles and Idioms (James Coplien) 有一节介绍了如何做这些可能对阅读有用的事情(尽管我不确定我会为此买一本只是)。

        【讨论】:

          【解决方案5】:

          查看 Boost.Reflection 和 Boost.Extension - 它们旨在解决尝试此类事情所涉及的各种问题。我很确定它仍然不允许您跨编译器或版本工作,但它可能对您有所帮助。

          【讨论】:

            【解决方案6】:

            我最初编写 v3c-dcom 只是为了看看我能不能做到 - 你可以从 Sourceforge 下载它。
            目前基本上只是一个插件系统。
            它依赖于其他三个 SourceForge 项目,因此您必须先下载并安装它们。

            转到 SourceForge http://sourceforge.net/ 并下载以下项目:
            * v3c
            * 树数据库
            * 元树数据库
            * v3c-dcom

            v3c 包含一个构建系统和一个通用实用程序库。
            treedb 包含核心“持久内存”功能。
            meta-treedb 将 treedb 内联实现封装在一个毯子中,从而缩短编译时间和代码膨胀。
            v3c-dcom 包含一些示例,包括在程序中创建插件存储库、向存储库添加库、调用 CoCreateInstance() 以创建对象以及调用这些对象的方法。

            我将构建系统设计为对用户友好,尽管它是基于 automake 的;)

            只需在每个项目的解压目录中依次执行make &amp;&amp; sudo make install即可。

            如果您偏执或没有“sudo”权限,请阅读 v3c 的 README 和有关如何在您拥有的目录下解压/构建/安装软件包的“试用”脚本。

            make check 将运行每个库,而对于 v3c-dcom,它将运行我上面提到的演示。

            希望这会有所帮助。

            【讨论】:

            • 感谢您的信息,欢迎访问该网站!顺便说一句,对于任何关心的人,我最终放弃了这个计划,只是因为 iOS 上的动态库受到限制,这是我的主要目标。而且我还认为,对于我正在做的任何事情,我都可以通过静态链接和实例化来获得类似的结果(与当时的“内置”代码相同)
            【解决方案7】:

            别忘了 XPCOM。它被设计成一个跨平台的 COM。

            【讨论】:

            • Firefox 就是基于它,每天都有很多人在使用它。 Office 基于 COM,每天都有越来越多的人使用它。
            猜你喜欢
            • 1970-01-01
            • 2016-01-22
            • 1970-01-01
            • 2016-05-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多