正如我在这个主题上的反思一样,在我看来,如果一种语言是用C++实现的,它很可能有一种链接到C++的机制.我记得,Java是通过JNI的方式,虽然我不记得它是通过C++还是简单的C.
但是,似乎一般语言不链接到C++,并且由于各种原因只能通过C访问C++.
因此,出于好奇,
哪些语言可以链接到C++以及如何以及在多大程度上?
(除非以优雅或有趣的方式完成,例如Boost.Python,否则上述C桥没有功劳)
注意:ABI包括名称修改以及调用约定,环境要求等.EABI(此处未涉及)是特定于平台的,但通常针对每个平台进行标准化(虽然这不能保证)并且不会受到影响可变EABI的问题(因为它没有太大变化).有关此主题的更多信息,请参阅维基百科上的ABI.
由于ABI未定义,因此不太可能链接到C++.因此,符号的名称可以根据编译器供应商的意愿而改变.例如,GCC与MS的编译器不同.即使使用相同的编译器,ABI在版本之间也可能不同(与某些GCC版本的情况一样).
但是,链接到C++并非不可能.C++程序链接到其他C++程序是很常见的,因为它们都是由相同的编译器(或至少使用相同ABI的编译器)编译的.如果ABI是已知的,非C++应用程序可以链接到C++应用程序.
链接到C很容易.这是因为对于大多数平台来说,C的ABI比C++ 的ABI更稳定.这是因为与C++相比,C的简单性.因为C++可以导出C符号,绕过C++的ABI问题,所以有时会看到C++库导出C符号,这些符号允许与底层C++对象进行交互,而不会出现名称损坏,链接兼容性和面向未来的问题.但是,这样做可以防止您通过C接口通过C接口轻松使用C++库.
但是您可以使用C导出来使用C++接口.该库可以在头文件中提供一些类,为您包装C导出.这是对图书馆作者的更多工作(并且可能会导致一些问题,因为DRY通常不会使用这种技术),但为图书馆用户提供了很多好处(可以在两个界面之间进行选择,而无需担心链接问题!).对于其他语言,库编写者可以提供类似C++头文件的接口,这些文件处理C导出本身.(然后,您可以使用本机类等.)
没有语言可以做得很好,因为C++标准没有指定名称修改方案.因此,不同的编译器可以自由地修改名称,并且没有一致的方法来链接到C++二进制文件.
这么多东西可以链接到C的原因是因为C具有简单且一致的链接.在目标文件中foo
调用一个函数foo
.同样,事情可以链接到Fortran的相当不错,因为foo
是一foo
,FOO
,foo_
,或foo__
.
这就是为什么有很多用于C++对象(SWIG,Boost.Python,SIP等)的包装生成器的原因.它们将接口定义为一组C调用,因为这样可以很容易地链接.
还需要记住的是,您是否真的想直接链接到C++库.生成包装器时,许多包装器生成器提供了许多策略选项.请记住,C调用归结为函数,但C++调用通常需要导航很多OO语义.您需要指定如何使用宿主语言对C++对象进行垃圾收集,如何复制内容,vptrs的位置,对象的布局方式,对象的分配位置以及宿主语言的对象模型与对象模型之间的所有细微差别. C++.
我知道仅仅链接到C++库并完成它是理想的,但它并不是那么简单,而且你最终还是想要不仅仅是直接链接.