10

我今天和一个同事在讨论。他声称用 C 语言编写 DLL 将允许以任何语言编写的任何其他应用程序使用该 DLL。但是,如果该 DLL 是用 C++ 编写的,那么可以使用该 DLL 的应用程序的数量是有限的(可能是因为语言限制)。

  1. 他说的对吗?
  2. 如果你要编写一个 DLL,它应该被用各种语言编写的各种应用程序使用(但在同一个平台上;让我们暂时忘记可移植性),你会用 C/C++ 编写它吗?为什么?

我希望这个问题不是大猩猩对鲨鱼的问题。如果是,请关闭它。

4

3 回答 3

13

大多数语言都提供了一种(简单的)方法来从 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++ 异常。

于 2013-05-24T08:08:44.953 回答
5

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"接口函数(并确保没有任何东西throws超出“C”的范围,因为这肯定会导致问题)。

结论: 显然,通过将接口限制为“仅使用 C++”,还有一个更复杂的情况是,任何使用 C、Python 或 Lisp 库的人[所有这些都可能相当容易地调用 C 函数],即用户必须将 C++ 代码包装在 C 语言包装器中。是的,这是可以做到的,并且当一些非常好的 C++ 库可用时经常使用,有人想要连接到具有可用 C 样式接口的语言。它与“在 DLL 中提供 C 到 C++ 接口”几乎相同的解决方案,只是它不是由 DLL 的生产者提供的。

于 2013-05-24T08:41:42.073 回答
0

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

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

于 2013-05-24T08:07:07.833 回答