热插拔C ++库可能吗?

时间:2010-06-23 16:45:57

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

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

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

动机是我的项目的状态机部分会经常更改并需要重新编译,也会允许主应用程序继续运行,同时加载不同的状态机。我希望使用一个“热插拔”库来安装Lua脚本之类的东西,因为有些担心,所以考虑到已经探索过它作为一种替代方案。

7 个答案:

答案 0 :(得分:17)

定义基础接口并从中派生您的实现。将它们放入动态库(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与我们二进制兼容,则不会进行实际检查。考虑一下,或者寻找现有的实现(其他一些在其他响应中提到)。

答案 1 :(得分:6)

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

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

Qt has a plugin framework

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

答案 2 :(得分:2)

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

答案 3 :(得分:2)

虽然它的很多部分已经过时,高级C ++编程风格和成语(James Coplien)有一节介绍如何做这些可能有用的内容(虽然我是我不确定我会为此购买 副本。)

答案 4 :(得分:2)

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

答案 5 :(得分:1)

我最初写的是v3c-dcom只是为了看看我是否可以这样做 - 你可以从Sourceforge下载它。
它基本上只是一个插件系统 它取决于其他三个SourceForge项目,因此您必须先下载并安装它们。

转到SourceForge http://sourceforge.net/并下载以下项目:
 * v3c
 * treedb
 * meta-treedb
 * v3c-dcom

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

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

依次在每个项目的解压缩目录中执行make && sudo make install

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

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

希望这有帮助。

答案 6 :(得分:0)

不要忘记XPCOM。它被设计成一个跨平台的COM。