10

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

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

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

4

7 回答 7

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 与我们二进制兼容,则不会进行实际检查。考虑一下,或者寻找现有的实现(在其他回复中提到了一些)。

于 2010-06-23T16:47:30.857 回答
6

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

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

Qt 也有一个插件框架

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

于 2010-06-23T16:52:11.380 回答
2

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

于 2010-06-23T16:48:22.133 回答
2

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

于 2010-06-23T16:51:02.143 回答
2

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

于 2010-06-23T16:51:26.183 回答
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 和有关如何在您拥有的目录下解包/构建/安装包的“试用”脚本。

make check will run each library through its paces and for v3c-dcom it will run the demo I mentioned above.

Hope this helps.

于 2011-02-27T22:16:43.083 回答
0

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

于 2010-06-23T16:56:46.807 回答