最近我对Apache如何支持Python WSGI很感兴趣。经过研究,我发现有一个mod_python模块,它是一个用C编写的共享库。此外,我还了解到Java提供了一种称为“JNI”的能力,使得Java可以通过编译共享来调用C代码库(.so)。
我很好奇编程语言如何解析编译的共享库(可能是二进制文件)并发出函数调用。他们如何沟通?特别是解释性语言和编译性语言如何合作?例如,Java被编译为字节码并在JVM上解释,这是一个单独的进程,JNI如何在其上执行外部C共享库?
任何帮助我理解的答案都值得赞扬。
Java被编译为字节码并在JVM上解释,这是一个单独的进程,JNI如何在其上执行外部C共享库?
JVM(在本例中是其中的 Java 字节码解释器)只是一个普通的本机程序,适用于您所在的任何平台。它采用字节码,查看每条指令,并执行指令指示它执行的任何操作。
因此,它调用共享库中的函数,就像计算机上的任何其他程序一样。它加载库,并使用系统提供的名称查找函数。这给了它一个指向函数开头的指针,它可以使用它跳转到该指令并调用它。
生成字节码的编译器以文本形式获取 Java 程序并生成字节码指令列表。如果您告诉它调用本机库中的函数,它需要如何调用该函数的描述(至少它采用什么参数类型及其返回类型)。然后它只是写出一条指令“加载这个库(如果需要)并调用其中包含该名称的函数”。
其中大部分不能直接用 C 或 Java 等语言完成,但用机器语言相当容易完成。因此,如果您想知道这是如何工作的,我建议您学习一些汇编程序。 68000 汇编器非常干净且易于理解,但任何汇编器都可以。你不需要深入学习它。学习如何在汇编程序中编写递归函数将教您需要知道的一切。
或者,有些库(如 libffi)实际上包含调用函数所需的机器代码,该函数的参数类型和返回类型直到运行时才知道,并将其包装在一个漂亮的 C API 中。该汇编语言代码对您来说意义不大,但可能会给您一个想法。
如果您对编译器和字节码解释器(如 Java 中的编译器和字节码解释器)如何工作感到好奇,我曾经制作过有关制作编程语言的视频教程。但是,虽然它都是用 C++ 编写的(与 Java 非常相似),但在您学习汇编程序的基础知识之前,我为什么要做某些事情可能并不真正清楚。