0

很晚了,我听说用不同语言编写的应用程序可以调用彼此的函数/子例程。现在,直到最近我都觉得那是很自然的——毕竟,是的——我当时就是这么想的,愚蠢的我!- 语言被编译成机器代码,所有语言都应该是相同的。直到不久前,我才意识到即使是用“高级机器码”(IL、字节码​​等)编译的语言也可以相互交互,实际上是应用程序。我试图找到很多次答案,但都失败了——没有一个答案让我满意——他们认为我对编译器了解很多,或者我完全不同意的东西,以及其他东西......请在很容易理解这是如何工作的。尤其是语言如何编译成“纯”

4

1 回答 1

0

这实际上是一个非常广泛的话题。编译为机器代码的语言通常可以调用彼此的例程,尽管通常并非不费力;例如,C++ 代码在正确声明时可以调用 C 例程:

// declare the C function foo so it can be called by C++ code
extern "C" {
    void foo(int, char *);
}

这很简单,因为 C++ 明确设计为与 C 兼容(它还支持从 C 调用 C++ 例程)。

调用约定确实使情况复杂化,因为一个编译器编译的 C 例程可能无法从另一个编译器编译的 C 调用,除非它们共享一个公共调用约定。例如,一个编译器可能会编译

foo(i, j);

到(伪组装)

PUSH the value of i on the stack
PUSH the value of j on the stack
JUMP into foo

而另一个可能会以相反的顺序推送和的值,或者将它们放在寄存器i中。j如果foo由编译器按照另一种约定进行编译,它可能会尝试以错误的顺序从堆栈中获取其参数,从而导致不可预测的行为(如果它立即崩溃,请认为自己很幸运)。

一些编译器为此目的支持各种调用约定。维基百科文章介绍了调用约定;有关更多详细信息,请参阅编译器的文档。

最后,在同一地址空间中混合字节码编译或解释语言和低级语言仍然更加复杂。高级语言实现通常带有自己的一组约定,以使用低级(C 或 C++)代码对其进行扩展。例如,Java 有JNIJNA

于 2012-04-21T17:08:51.227 回答