非托管C ++:如何动态加载代码?

时间:2009-12-09 19:57:36

标签: c++ dll

我们的行业是高性能的分布式并行计算。我们使用Visual Studio 2008开发了一个非托管C ++应用程序。

我们的应用程序(更像框架)应该能够动态加载由第三方开发的代码(算法)(可以有许多dll)符合我们的接口规范,并调用加载的代码来获得一些结果。

把它想象成你想调用sin(x)函数,但是你可以使用sin(x)的许多不同实现。

我有几个问题,因为我对动态加载代码的这个领域很陌生:

  1. dll(动态链接库)是否满足此类要求的答案?
  2. 如果第三方使用不同类型的IDE来创建dll而不是我的(比如Eclipse CDT,C ++ Builder,Visual C ++ 6.0等),dll是否仍然可以与我的应用程序一起使用?
  3. 我们的应用程序也应该跨平台工作(应该能够在Linux上运行),使用QLibrary是最合理的方式来抽象掉所有特定于平台的dll加载吗?
  4. (可选)我可能会遇到一些无法预料的问题吗?

3 个答案:

答案 0 :(得分:3)

1)一般来说,是的。如果API变得复杂且多对象,我会使用COM或类似的机制。但是如果你只需要管理一个小状态,或者可以完全无状态,那么纯DLL接口就可以了。

2)使用合适的调用约定(stdcall)和数据类型。我甚至不认为实现必须在C ++中。所以这意味着char / wchar_t,显式大小的int,例如int32,float和double,以及它们的C风格数组。

3)不能说

4) 没有跨境内存分配:免费分配,让插件免费分配。

您的API设计对可实现的性能和实施工作有很大影响。不要使函数变小,给实现一些自由处理某些事情,定义错误协议,线程要求等。

<强> [编辑]
此外,如果您声明结构,请查看对齐和编译器选项来控制它(通常是#pragma pack)。这是必需的,因此客户可以看到相同的布局。

编译器通常会“修改”导出符号的名称(例如,为STDCALL约定添加udnerscore)。通常,这是通过传递给链接器的.def文件来控制的。

答案 1 :(得分:1)

  1. 是的,确实如此。但是有很多问题。
  2. 可能是也可能不是。首先,您应该了解calling conventions。其次,由于C ++没有标准化的ABI,你应该在接口级别坚持使用普通的C(顺便说一下,COM技术就是这个 - 制作标准化的ABI)。第三,每个插件可能都有自己的CRT,因此可能会出现问题,MSDN上有一个很好的article
  3. 是的,这有助于加载动态库,但不会出现(2)中的问题。虽然这些问题主要是针对Windows的。

答案 2 :(得分:0)

根据我的经验,QLibrary是您问题的最佳答案。 它提供了一个简单的界面,并负责所有特定于平台的细节。 实际上,这意味着插件也必须使用QT编写。