Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JVM动态函数调用_Java_C_Dynamic_Jvm_Java Native Interface - Fatal编程技术网

Java JVM动态函数调用

Java JVM动态函数调用,java,c,dynamic,jvm,java-native-interface,Java,C,Dynamic,Jvm,Java Native Interface,我目前正在寻找JVM的引擎盖下,OpenJDK JVM的引擎盖是特定的。我想知道JVM是如何调用本机函数的。我知道它动态加载它们并将它们保存为void*,但我似乎找不到实际的调用部分 例如: jint Java_Test_add(jobject*, jint); 可以是本机c函数,但也可以是: jvoid Java_Test_main(jobject*); 所以现在我想知道JVM如何在运行时将方法签名作为字符串调用这些函数。据我所知,C不支持这种动态调用。我希望有人能告诉我这是如何工作的,或

我目前正在寻找JVM的引擎盖下,OpenJDK JVM的引擎盖是特定的。我想知道JVM是如何调用本机函数的。我知道它动态加载它们并将它们保存为
void*
,但我似乎找不到实际的调用部分

例如:

jint Java_Test_add(jobject*, jint);
可以是本机c函数,但也可以是:

jvoid Java_Test_main(jobject*);
所以现在我想知道JVM如何在运行时将方法签名作为字符串调用这些函数。据我所知,C不支持这种动态调用。我希望有人能告诉我这是如何工作的,或者如何解决这样的问题


提前谢谢

您可以通过以下两种基本方法之一解决此问题:

  • 编写一些特定于平台和机器的代码,理解调用约定并正确设置。(参见libffi,了解广泛用于发动机罩下的示例)
  • 编写大量的C函数,这些函数接受varg并根据类型分派它们 C不支持这种动态调用

    事实上是的。它们被称为动态的,因为它们可以在运行时加载,并且它们的代码可以通过符号名链接

    DLL(Unix术语中的共享库)通常包含一个符号表,用于将符号名称映射到函数的地址。操作系统提供API以通过名称解析地址,例如在POSIX或Windows上

    JVM基本上使用此API在本机方法的第一次调用中查找函数地址。然后它记住解析的地址,以便以后的调用直接通过该地址完成

    将本机方法绑定到函数地址的另一种方法是调用JNI函数。调用者提供指向本机函数的直接指针,本机函数不一定按照标准JNI命名约定命名


    这就是本机方法链接的工作原理。描述了调用本机方法的过程。

    每种语言都有自己的过程调用约定(如何执行对子例程的调用,应该将什么放入堆栈或寄存器中,必须执行什么才能从子例程返回),以及在这种情况下,从Java调用用C编写的本机方法会发生什么,jvm需要模仿C调用约定,在其正常上下文之外执行您编写的方法
    Java\u Test\u add

    方法签名将用于获取对内存中C函数位置的引用(从编译项目时链接的静态库加载),invoke_本机指令实现(每个jvm实现不同)将负责执行调用并处理返回(这可以手动完成,但正如有人所说,有libffi这样的库实现了各种调用约定)

    因此,您不必从C语言特性的角度来看待这一点,因为是的,该语言没有提供一些简单的语法糖来在运行时执行这种“动态”调用,但这仍然可以实现,最终会在混合中添加一些汇编