如何组合不同的编程语言

时间:2011-07-20 19:42:50

标签: programming-languages linker compilation

没有询问WHEN 链接不同的编程语言。

这是一个非常普遍的问题,但我个人在Linux上工作。

我想要了解的是不同编程语言的过程 结合起来,我发现了一篇关于结合C / C ++ / Fortran的好文章: http://www-h.eng.cam.ac.uk/help/tpl/languages/mixinglanguages.html

据我所知,大多数编译器执行两个阶段:

  1. 将语言文件翻译成包含机器代码但仍然存在的目标文件 包含一些符号(可能是函数名?)

  2. 将目标文件链接在一起,只有在此阶段,链接器才会检查这些功能 在目标文件中是可调用的。

  3. 我认为组合不同语言的问题是名称错误,这意味着 当函数的名称变为目标代码时,它们的名称会发生​​变化。

    问题是:

    1. 你不能以某种方式预先发现受损的函数名称,而不是在编程语言中明确地指定它们或者更好地指出它们,是不是已经有了这样的软件?

    2. 我完全不了解动态库的链接方式,但可以使用不同的语言 通过程序与动态库交互的相同方法进行交互?

    3. p.s主要目的是调用用另一种语言编写的函数。

4 个答案:

答案 0 :(得分:6)

将不同目标文件链接在一起的问题通常归结为子程序调用约定。基本上,当您调用另一个目标文件中的例程时,您的编译器必须知道其他对象文件将在内部命名其例程,如何传递其所有参数,以及(如果有)设置和清理代码例程将需要。所有这些内容通常在calling convention s。的标题下组合在一起。

每个编译器都有自己喜欢用于子例程的调用约定。注意我说“编译器”,而不是语言。 Linux中的C调用约定与Windows上的C调用约定不同。

因此,当您混合语言时,您需要某种方式告诉编译器调用或调用子例程以使用其他语言的调用约定。 C的约定是一种流行的用法,因为几乎每个平台都有一个C编译器。但是,某些平台(例如:Windows)具有多种流行的调用约定。

现在我们在评论中提出您提出的问题:

  

是否有一种“告诉编译器使用其他语言的调用约定”的常用方法?

答案是,“不,不是真的”。有些语言确实使用了特定的其他语言的调用约定。例如,C ++允许您在声明上放置extern "C"以告诉编译器有问题的声明使用C调用约定。 Ada用pragma Convention (X,...)完成同样的事情,其中​​X是约定名称。 CFortranCobol由语言定义,但支持的任何其他内容(例如:Windows“Stdcall”都是实现定义的。

但是,如果你有一对编译器编写者从未想过彼此的语言,那么你别无选择,只能告诉两者使用他们都知道的第三种约定(通常是C)。例如,要使标准 C ++和Ada进行互操作,您需要使用C约定将服务器代码导出其例程,并告诉客户端代码它正在调用的例程正在使用C约定

答案 1 :(得分:1)

不同的语言绝对可以使用相同的库。例如,在旧的Windows Visual Basic上,动态加载Windows API函数是很常见的。

语言间链接所需要的只是函数调用约定的协议,以及函数名称的知识。前者必须通过查阅文档来完成;必须在创建对象或库的编译器中查找后者。例如,gcc将编译C而不包含名称,因此您可以直接引用C源代码中的函数名称,而g++将编译带有错误名称的C ++代码,您最好通过extern "C"声明公开C函数。

基本上,只要您的对象或库只公开C ABI,就应该广泛支持绑定到其他语言。例如,如果要使用本机C ++库,则要困难得多,因为在这种情况下,您的外语必须实现正确的C ++ ABI。它类似于从Fortran导出代码,但我相信可以使用C ABI。

答案 2 :(得分:0)

“标准”是在组合来自不同语言的程序时使用非损坏的名称。通过使用extern "C"声明特定符号,可以为C ++中的特定符号关闭名称修改。 C不会破坏名字。

答案 3 :(得分:0)

所有库可执行文件都包含某种类型的接口。如果他们没有,那么任何软件都无法与他们合作。内部方法更有可能变得更有效率。此外,许多语言允许您在编译器级别关闭“修改”。

链接,作为一个简单的解释(我可能会对此感到厌烦?),正在打包成一个文件。这些类保留与非链接库相同的接口,至少从外部编程的角度来看。