我今天在和一位同事讨论。他声称用C编写DLL将允许用任何语言编写的任何其他应用程序使用该DLL。但是,如果该DLL是用C++编写的,则可以使用该DLL的应用程序数量有限(可能是由于语言限制)。
我希望这个问题不是Gorilla vs. Shark的问题。如果是,请关闭它。
发布于 2013-05-24 08:08:44
大多数语言都提供了一种从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-24 08:41:42
1)如果DLL提供的接口确实是一个C++接口,那么是的,这使得其他语言很难(如果不是不可能)与DLL接口。
C++与C的接口比C更复杂,因为类的结构更复杂(this指针正在传递,虚拟函数指针/VTABLE布局)和异常处理(其中被调用的代码必须以某种方式处理异常发生的事实,要做到这一点,代码需要“解除”抛出异常的代码的调用堆栈,并销毁在途中创建的任何对象,直到找到一个catch --如果在DLL中的调用堆栈中没有出现这种情况,您就会遇到问题--这种展开不是C++标准的一部分,由于标准不希望限制处理器需要哪些体系结构和什么特性,因此/必须实现C++ (而不是必要的)。捕获DLL中的异常将解决这里的问题。
换句话说,如果该语言不是C++,并且可能来自调用代码的同一个供应商,则需要对任何正在调用它的语言进行C++处理。这会变得很复杂。
任何C++对象都需要在调用代码中从/转换到相关语言。对于与C相同的基本类型,这通常不是一个问题,但是类、结构等必须与本地语言中兼容的东西相匹配。
另一方面:C函数很容易与:将参数放在堆栈上,调用函数,并在返回时清理参数。没有奇怪的事情发生,没有隐藏的函数参数,不需要展开堆栈。唯一稍微复杂的是返回一个struct (大于某个大小)的函数--但在C. C中,这是一个非常特殊的情况,它的“objet”要简单得多,而且大多数语言的类型都与基本的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-24 08:07:07
每种语言都有自己的特点,如调用约定、堆栈设置等。每当您试图处理跨越语言边界的函数调用时,您都必须处理这个问题。编译器通常支持各种各样的调用约定,因此您必须确保定义和编译是正确的,然后可以使用任何语言与来自其他模块的模块进行通信。从一种语言或另一种语言中比较容易或更难这样做的说法是不正确的,因为你总是要在某个时候处理这个问题。
我选择的语言最适合我的任务,而不是相反的方式。在编写GUI应用程序时,我通常使用Java,因为Java允许我专注于解决方案,而不是跟踪内存。)当我想要性能时,我使用C或C++,甚至汇编程序,所以语言的选择取决于我打算用它做什么,或者我的环境看起来如何。
https://stackoverflow.com/questions/16730284
复制相似问题