【问题标题】:What is the correct way to write native method signatures in Android NDK?在 Android NDK 中编写本机方法签名的正确方法是什么?
【发布时间】:2011-05-01 04:25:41
【问题描述】:

我有一个 NDK 库和相应的 Java 类的工作实现。但我无法向该类添加重载方法。目前我的课程包含:

package com.package;

public class MyClass
{
  public static native String getFileName();
  static
  {
    System.loadLibrary("mylib");
  }
}

我的 jniwrappers.cpp 文件有以下声明:

JNIEXPORT jstring JNICALL
Java_com_package_MyClass_getFileName(_JNIEnv* env, jobject thiz);

到目前为止,一切正常。但接下来我修改我的课程:

package com.package;

public class MyClass
{
  public static native String getFileName();
  public static native String getFileName(int index);
  ...
}

并在 jniwrappers.cpp 中添加另一个声明:

JNIEXPORT jstring JNICALL
Java_com_package_MyClass_getFileName__I(_JNIEnv* env, jobject thiz, jint index);

它编译良好,Android 应用程序启动,没有得到 UnsatisfiedLinkError 但是当它使用参数调用第二个方法时,第一个 C++ 函数被调用,但不是第二个。我在该类中有其他带有参数的方法,但它们都没有被重载,因此它们各自的 JNI 签名不包含参数。

那么,我做错了什么?

【问题讨论】:

    标签: java-native-interface android-ndk


    【解决方案1】:

    您应该使用javah 工具来生成这些签名。

    要使用它,请在您拥有native 函数的地方构建类文件。你会得到一个class 文件。

    运行javah -jni com.organisation.class_with_native_func,它会为你生成一个头文件。

    这比自己编辑要干净得多。

    【讨论】:

    • 谢谢,这就是我应该使用的。但仍然了解内部结构非常有用。
    • 或者直接使用 -classpath 命令行开关将 javah 指向编译类文件的目录(即:javah -classpath /path/to/jar -jni com.package.name.YourClass)。
    【解决方案2】:

    您必须在原始 getFileName 函数的末尾添加一个__,因为它已重载。您的 2 C 函数原型现在应该如下所示:

    JNIEXPORT jstring JNICALL Java_com_package_MyClass_getFileName__
      (JNIEnv *, jclass);
    
    JNIEXPORT jstring JNICALL Java_com_package_MyClass_getFileName__I
      (JNIEnv *, jclass, jint);
    

    【讨论】:

    • 这是我尝试的第一件事,但出了点问题,我得到了 UnsatisfiedLinkError。现在我重试了,一切正常。非常感谢!
    猜你喜欢
    • 2016-08-28
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 2017-04-20
    • 1970-01-01
    相关资源
    最近更新 更多