用C编写的DLL与用C ++编写的相同

时间:2013-05-24 08:00:53

标签: c++ c dll code-reuse

我今天和同事讨论过。他声称用C语言编写DLL将允许使用任何语言编写的任何其他应用程序来使用该DLL。但是,如果该DLL是用C ++编写的,则可能使用该DLL的应用程序数量有限(可能是由于语言限制)。

  1. 这样说是对的吗?
  2. 如果你要写一个应该被各种语言编写的各种应用程序使用的DLL(但是在同一个平台上,让我们忘记一点可移植性),你会用C / C ++编写它吗?为什么?
  3. 我希望这个问题不是Gorilla vs. Shark有点问题。如果是,请关闭它。

3 个答案:

答案 0 :(得分: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 :(得分:4)

1)如果DLL提供的INTERFACE确实是C ++接口,那么是的,这使得其他语言与DLL接口变得困难(如果不是不可能的话)。

C ++与C的接口更复杂,因为类的结构更复杂(传递this指针,虚函数指针/ VTABLE布局)和异常处理(被调用的代码必须处理)异常以某种方式发生的事实,并且要做到这一点,代码需要能够“解开”抛出异常的代码的调用堆栈并销毁在路上创建的任何对象,直到它找到{{ 1}} - 如果在DLL中的调用堆栈中不存在这些问题 - 这个展开不是C ++标准的一部分,因为标准不希望限制处理器需要/应该使用哪些体系结构和功能必须实现超过必要的C ++)。捕获DLL中的异常将解决此处的问题。

换句话说,如果语言不是调用代码的C ++ [并且可能来自同一供应商],那么无论语言是什么语言,都需要对C ++进行一些处理。这可能会非常复杂。

任何C ++对象都需要从/向调用代码中的相关语言翻译。对于与C相同的基本类型,这通常不是问题,但是类,结构等必须与本地语言兼容的东西相匹配。

另一方面:C函数很容易与之接口:将参数放在堆栈上,调用函数,并在返回时清理参数。没有什么奇怪的事情发生,没有隐藏的函数参数,不需要展开堆栈。唯一的轻微复杂因素是函数返回catch(大于特定大小) - 但这在C中是一个非常特殊的情况.C的“objets”要简单得多,并且大多数语言的类型都与基本的C语言类型(但C风格struct仍然可能会导致一些有趣的问题,如果“聪明地”使用它,struct可能是一个真正的挑战。

2)选择语言是一项复杂的业务,它在很大程度上取决于DLL应该如何使用或者应该提供什么样的接口,以及它本身应该连接到哪些接口 - 如果你的DLL是接口的话到另一个C ++ DLL(或其他一些C ++代码),那么你可能想要使用C ++。但有一些方法可以生成一个具有C接口的C ++ DLL,通过使用union作为接口函数(并确保墙上没有任何extern "C"到“C”,因为这肯定会导致问题)。

<强>结论: 显然,通过将接口限制为“仅使用C ++”,那么使用来自C,Python或Lisp的库(所有这些都可以相当容易地调用C函数)的任何人都会进一步复杂化,该用户将必须将C ++代码包装在C语言包装器中。是的,这可以完成,并且当C ++中有一些非常好的库时,它会被定期使用,有人想连接到具有C风格接口的语言。它与“在DLL中提供C到C ++接口”的解决方案几乎相同,除了它不是由DLL的制作者提供的。

答案 2 :(得分:0)

每种语言都有它自己的characeristics,如调用约定,堆栈设置和其他东西。每当您尝试处理跨越语言边界的函数调用时,您必须处理此问题。编译器通常支持多种调用约定,因此您必须确保定义和编译是正确的,然后您可以使用任何语言与其他语言的模块进行通信。 这样的陈述,使用一种语言或另一种语言更容易或更难做到,这是不正确的,因为你总是必须在某个时候处理这​​个问题。

我选择最适合我的语言,而不是相反。当我编写GUI应用程序时,我通常使用Java,因为它让我专注于解决方案而不是跟踪内存。 :)当我想要性能时,我使用C或C ++甚至汇编程序,因此语言的选择取决于我打算用它做什么或我的环境看起来如何。