Java JNI 围绕 java 函数及其 C 实现

标签 java java-native-interface

首先我想说的是,请不要要求我使用 javah 工具,我编写几个 jni 函数原型(prototype)比让该工具正常工作更幸运。

我知道我正在正确加载 jni 库,因为当我保持类结构不变时它们可以工作。

我有一些包名称: 包 com.bb.me;

public class test {

  test2 iTest = null;

  public parent test()
  {
    iTest = new test();
    return iTest;
  }

  //putting my native methods here work just fine
  //public native void init();
  //etc

}

上述函数的 c jni 函数原型(prototype)如下所示:

JNIEXPORT void JNICALL Java_com_bb_me_test_init(JNIEnv* e, jobject i) {}

如果我通过重命名它 inita 来破坏上面的函数签名并调用该函数,我会收到如下错误:

未找到 native Lcom/bb/me/test;.init:()V 的实现

如果另一方面我将 native 函数移动到内部类,如下所示:

class test2 extends parent {
//public native void init();
}

然后尝试调用相同的函数,jni 会以不同的方式向我提示未实现的函数,但这一次它看起来像这样:

未找到 native Lcom/bb/me/test$test2;.init:()V 的实现

我最初想如果我将 jni 函数签名编辑为如下所示:

JNIEXPORT void JNICALL Java_com_bb_me_test_test2_init(JNIEnv* e, jobject i) {}

该函数可以工作,但情况似乎并非如此。

此 jni 函数签名中的“$”美元符号是什么意思?

未找到 native Lcom/bb/me/test$test2;.init:()V 的实现

如何在不使用 javah 工具的情况下移动此 native 函数的位置并更新 jni 函数签名?

最佳答案

I'd like to start by saying please don't ask me to use the javah tool, I've had more luck writing the few jni function prototypes than getting that tool to work properly.

我不会要求你使用javah——虽然很难不这样做——但我至少必须说我发现这个评论令人惊讶。我发现 javah 确实非常容易使用。如果它不适合你,那么我倾向于怀疑你有错误的期望。

What does the "$" dollar sign mean in this jni function signature?

$ 将嵌套类的简单名称与其嵌套类的名称分隔开。这是 JVM 内部名称表示的一个方面,也是 JNI 的工作原理。

How can I move the location of this native function and update the jni function signatures without using the javah tool?

您可以引用Oracle's documentation for mapping Java native method names to C function names 。预期的 native 函数名称基于 native 方法类的完全限定 JVM 名称、 native 方法的非限定名称以及其签名(如果重载)。如果将 native 方法移动到不同的类,那么您需要更改函数名称以反射(reflect)新位置,并且您可能还需要将函数签名编码到名称中(如果尚未完成)。

内部类的 JVM 名称是 com/bb/me/test$test2。假设该方法未重载,则与该类中的 native 方法相对应的 C 函数名称将为 Java_com_bb_me_test_00024test2_init()。参数则不同——它们取决于 Java 端方法的参数以及 native 方法是否是静态的。我不在这里讨论它们。

关于Java JNI 围绕 java 函数及其 C 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32724541/

相关文章:

java - 多线程: the best way when write duplicated data

java - 按下 JButton 时 Swing 获取 JTextField

Android JNI 异常处理

java - 是否可以通过 JNI 将静态库链接到 Java?

java - 如何通过 Java 代码影响 System.loadLibrary() 的搜索路径?

java - 如何指示 yum 安装特定版本的 OpenJDK

java - 根据条件不同的覆盖方法

java - 从Java调用Python并传递参数时出错

c - jni-wrapper 在 Windows 上使 JVM 崩溃

android - 通过信号调用 Android NDK 项目中的 ffmpeg 部分来终止进程