Ani*_*amy 9 c c++ dll code-reuse
我今天和同事讨论过.他声称用C语言编写DLL将允许使用任何语言编写的任何其他应用程序来使用该DLL.但是,如果该DLL是用C++编写的,则可能使用该DLL的应用程序数量有限(可能是因为语言限制).
我希望这个问题不是大猩猩与鲨鱼有点问题.如果是,请关闭它.
Mat*_*get 11
大多数语言提供了一种(简单)方法从DLL调用C函数.C++不是这种情况,因为C++ ABI(C++函数的二进制接口)是特定于供应商的.
除此之外,几乎不可能与使用高级 C++结构(如模板或STL)的C++ DLL进行交互.
但是,DLL的内容可以用C++编写,您只需要确保您的接口符合C标准.要做到这一点,不要在你的界面中使用C++构造并用你的声明包围你的声明:
#ifdef __cpluscplus
extern "C" {
#endif
/* You declarations here */
#ifdef __cpluscplus
}
#endif
...这样,你用C接口包装你的C++库.
编辑:正如Mats Petersson写的那样,不要忘记确保在包装器中处理每个可能的C++异常.
1) 如果 DLL 提供的 INTERFACE 确实是 C++ 接口,那么是的,其他语言很难(如果不是不可能的话)与 DLL 接口。
C++ 的接口比 C 更复杂,因为类的结构更复杂(this传递的指针、虚函数指针/VTABLE 布局)和异常处理(其中被调用的代码必须处理异常发生在某些方式,为此,代码需要能够“展开”引发异常的代码的调用堆栈并销毁在途中创建的任何对象,直到找到catch- 如果调用堆栈中不存在该对象在 DLL 中,您会遇到问题 - 这种展开不是 C++ 标准的一部分,因为该标准不希望限制处理器需要/应该比必要更多地实现 C++ 的架构和特性)。在 DLL 中捕获异常将解决这里的问题。
换句话说,如果语言不是调用代码的 C++ [并且可能来自同一供应商],则需要对 C++ 进行某种处理以处理调用它的任何语言。这可能会变得非常复杂。
任何 C++ 对象都需要在调用代码中从/转换为相关语言。对于与 C 相同的基本类型,这通常不是问题,但是类、结构等必须与本地语言中兼容的内容相匹配。
另一方面:AC 函数很容易与之交互:将参数放在堆栈上,调用函数,并在返回时清理参数。没有什么奇怪的事情发生,没有隐藏的函数参数,不需要展开堆栈。唯一稍微复杂的地方是函数返回 a struct(大于某个大小)——但这在 C 中是一个非常特殊的情况。C 的“对象”要简单得多,而且大多数语言的类型都与基本的 C 语言类型很好地对应(但是 C 风格struct仍然会引起一些有趣的问题,union如果“巧妙”地使用它,它可能是一个真正的挑战)。
2) 选择语言是一项复杂的工作,它在很大程度上取决于 DLL 应该如何使用或它应该提供什么样的接口,以及它本身应该连接到什么接口 - 如果您的 DLL 与另一个 C++ 接口DLL(或其他一些 C++ 代码),那么您可能想要使用 C++。但是有一些方法可以生成具有 C 接口的 C++ DLL,方法是使用extern "C"for 接口函数(并确保没有throws越过“C”的墙,因为这肯定会导致问题)。
结论: 显然,通过将接口限制为“仅使用 C++”,那么任何人都使用来自 C、Python 或 Lisp 的库 [所有这些都可能相当容易地调用 C 函数],这会带来进一步的复杂性用户必须将 C++ 代码包装在 C 语言包装器中。是的,这是可以做到的,并且在 C++ 中有一些非常好的库可用时经常使用,有人想连接到具有 C 风格接口的语言。它与“在 DLL 中提供 C 到 C++ 接口”的解决方案几乎相同,只是它不是由 DLL 的生产者提供的。