c - 尝试理解 JNI.h 中的 C 函数调用

标签 c java

我正在深入研究 Java 的 OpenJDK 源代码,希望了解一些有关 CallStaticVoidMethod 的知识。但我很难做到这一点。

这就是我被踩的地方:

00535     void (JNICALL *CallStaticVoidMethod)
00536       (JNIEnv *env, jclass cls, jmethodID methodID, ...);

如果我粗略的 C 知识是正确的,这看起来像是一个函数调用(到哪里?)。也许可能是在调用一些已经编译的库?

(JNICALL只是一个调用约定) JNICALL 似乎是 __stdcall ( What is __stdcall? )

这是该文件的完整源代码: http://xdprof.sourceforge.net/doxygen/jni_8h-source.html

谢谢

最佳答案

也许它正在调用一些已经编译的库?

是的 - 我认为您需要一些有关 JNI 的背景知识。让我尝试快速提供背景信息,因为我认为这会消除您的困惑,或者至少让您走上正确的道路。

Java 运行时无法在 Java 上运行 - 它们是作为 native 可执行文件实现的。

JNI(Java native 接口(interface))本质上是一个 native 接口(interface),用于要求 Java 运行时执行各种操作。

在众多其他功能中,您可以使用 JNI 来调用用 Java 实现的方法

JNI 有许多不同的辅助方法来调用不同类型的方法。

您所询问的方法(特别是CallStaticVoidMethod)将用于调用Java函数,例如本示例中的函数: public static void DoSomething() { ... }

为了让运行时调用该方法,它需要了解一些信息 - 例如:有关当前运行时/上下文/环境的信息(这是 JNIEnv * env 参数),声明静态方法的类(这是 jclass cls 参数)、要调用的方法(这是 jmethodID methodID 参数)。

编辑:

您的回复的后续内容:

我在OpenJDK代码中没费多大劲就找到了它。

http://hg.openjdk.java.net/

cvmi/cvmi/jdk 通用虚拟机接口(interface)

http://hg.openjdk.java.net/cvmi/cvmi/jdk/archive/tip.zip

下:

./src/share/javavm/export/jni.h

void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) {
    va_list args;
    va_start(args,methodID);
    functions->CallStaticVoidMethodV(this,cls,methodID,args);
    va_end(args);
}

我不知道它被分配在哪里:functions->CallStaticVoidMethodV,但我确信如果您费尽心思下载各个组件的所有源代码,您会发现一个结构体使用该成员和/或对该函数指针的赋值 - 您可以从那里开始。

因为它应该是多个运行时的标准/通用接口(interface),所以如果实际实现和通过 JNI 公开的方式之间存在某种间接层,我不会感到惊讶。

关于c - 尝试理解 JNI.h 中的 C 函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9434581/

相关文章:

c99 转到过去的初始化

c++ - 使用 gcc 编译器时,未在此范围内声明“memcpy”

java - 你能在性能良好的 JPA 实体中使用 lambda 表达式吗?

c++ - pcap_next_ex() 永远不会将指针设置为原始数据包?

python - 如何测试 PyObject 是否有迭代器

java - Java 中的 getConstructor 抛出 NoSuchMethodException

java - 如何在 RequestParm 中将多个值转换为枚举?

java - Struts2日期标签显示工作日,如Wed, 13 Feb, 2013 9 :00 AM

java - 计算特定字符之间的字符数(包括空格)

C : How to detect if execvp waiting for standard input?