Compilation 用不同语言编写的不同应用程序如何交互?

Compilation 用不同语言编写的不同应用程序如何交互?,compilation,subroutine,Compilation,Subroutine,最近我听说用不同语言编写的应用程序可以调用彼此的函数/子例程。现在,直到最近,我觉得这是很自然的-因为,是的,所有-那是我当时的想法,愚蠢的我语言被编译成机器代码,所有语言的机器代码应该是相同的。直到不久前,我才意识到,即使是用“更高的机器代码”(IL、字节码等)编译的语言也可以相互作用,实际上,应用程序也是如此。我多次试图找到答案,但都失败了——没有一个答案让我满意——要么他们认为我对编译器了解很多,要么我完全不同意某些东西,还有其他一些东西……请以一种易于理解的方式解释这是如何实现的。尤其是

最近我听说用不同语言编写的应用程序可以调用彼此的函数/子例程。现在,直到最近,我觉得这是很自然的-因为,是的,所有-那是我当时的想法,愚蠢的我语言被编译成机器代码,所有语言的机器代码应该是相同的。直到不久前,我才意识到,即使是用“更高的机器代码”(IL、字节码等)编译的语言也可以相互作用,实际上,应用程序也是如此。我多次试图找到答案,但都失败了——没有一个答案让我满意——要么他们认为我对编译器了解很多,要么我完全不同意某些东西,还有其他一些东西……请以一种易于理解的方式解释这是如何实现的。尤其是编译成“纯”机器代码的语言如何拥有不同的称为“调用约定”的东西,这让我毛骨悚然。

这实际上是一个非常广泛的话题。编译成机器代码的语言通常可以调用彼此的例程,尽管通常不是没有努力的;例如,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);
到(伪汇编)

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

一些编译器为此支持各种调用约定。引入呼叫约定;有关更多详细信息,请参阅编译器的文档


最后,在同一地址空间中混合字节码编译或解释语言和低级语言更为复杂。高级语言实现通常有自己的一套约定,用较低级别(C或C++)的代码来扩展它们。例如,Java有和。

thanx很多…我想我已经理解了它,但我只是这么想…也许我还有其他疑问。。。是的…我们都说程序“崩溃”到底是什么意思?我是说在低级意义上…这个短语我已经见过很多次了,不能确切地理解它的意思…还有一件事…计算机如何区分两个对象-就像我们在更高级的行话中使用对象一样,但在编译语言中,所有这些都归结为0和1……那么comp如何知道第n位是对象的结尾呢?或者简单地说,它怎么能把2个整数分开呢?毕竟内存是一个按一定顺序排列的位流,对吗?@ParthThakkar:崩溃意味着你的程序突然停止运行。至于你的第二个问题,一般来说,这几乎不可能解释清楚。你熟悉C++吗?是的…我一直在用多种语言,当然可以写大型程序……但是我想知道的是低级细节……就像它们有点神秘,你知道!我甚至知道一些汇编的基础知识——只是一些基础知识,比如,我可以阅读一些简单的代码并理解它的功能……所以请随意插入一些较低级别的细节…@ParthThakkar:那么你可能想把这作为一个单独的问题。我无法在评论框中找到一个像样的答案。
PUSH the value of i on the stack
PUSH the value of j on the stack
JUMP into foo