【发布时间】:2011-10-21 20:50:27
【问题描述】:
如果我用 C++ 编写了一个库,并且绑定了 C, Ada, Fortran, D 和其他编译语言。
所有这些绑定是否可以与 C++ 编译代码在同一个二进制文件中,即使它们使用相同的函数名?
你可以使用这样的绑定吗?
【问题讨论】:
-
可能不会,但我真的不知道。
如果我用 C++ 编写了一个库,并且绑定了 C, Ada, Fortran, D 和其他编译语言。
所有这些绑定是否可以与 C++ 编译代码在同一个二进制文件中,即使它们使用相同的函数名?
你可以使用这样的绑定吗?
【问题讨论】:
根据您创建绑定的方式,可能甚至不需要库:
例如,使用 MRI API 编写的 ruby 扩展基本上是一个共享库,提供:
void init_Modulename()
然后,此函数使用 MRI API(如 rb_define_module、rb_define_class、rb_define_method 等)来包装 C/C++ API。确保这个函数被 extern "C" 包围,这样它的名字就不会以 C++ 的方式被破坏。
通常这个共享库会链接到您正在绑定的库,但没有什么可以阻止它们是同一个共享库。
例如在 Ruby 和其他解释器上使用 FFI 的绑定。绑定使用相同的语言定义,FFI 库知道如何在运行时调用目标库中的方法。因此在这种情况下,绑定本身没有“库”。
如果您使用 SWIG 之类的生成器,它将扫描库标头并生成各种语言的绑定。根据 SWIG 生成器如何实现这些目标(例如,对于 Ruby,使用上述 MRI API),然后 SWIG 将创建可以编译到其自己的库中的代码,但只要您没有符号冲突,您也可以将其与您的库一起编译。
当我指的是符号冲突时,我指的不是 API 本身,而是绑定助手,例如 init_Modulename()。
【讨论】:
您可以将 C++ 与 C 链接,前提是您只调用 C 风格的函数(在对象之外)并且通过“extern C”在标题中关闭了名称修改。特别是如果您使用相同的编译器。不同的编译器如果使用不同的 obj 格式会导致问题。我不了解 ADA/Fortran/D,但我怀疑答案是否定的,至少直接通过 .LIB 或 .OBJ 文件。在 windows 上,如果 ADA/FORTRAN/D 支持动态链接,您可以通过 DLL 尝试(或者您可以调用 windows api LoadLibrary)。
这不是一件容易的事,我掩盖了细节。如果您真的要尝试,那么您需要具体说明您正在使用哪些平台和编译器,我会尝试更具体。
【讨论】:
是的。一个例子(稍微颠倒)是PlPlot;它是用 C 语言编写的,并绑定到 Ada、C++、D、Fortran77、Fortran95、Java、Lua、OCaml、Python ......
【讨论】: