JNI:javah mangles参数是内部类

时间:2016-05-14 18:46:36

标签: java android c++ java-native-interface javah

我有一个JNI函数,它将android.graphics.Bitmap$Config作为参数传递。 ConfigBitmap的内部类。当我运行javah时,我得到了不正确的标题签名(截断为单个参数):

Landroid_graphics_Bitmap_Config

相当于:

Landroid/graphics/Bitmap/Config

而不是:

Landroid_graphics_Bitmap_00024Config

是等效的

Landroid/graphics/Bitmap$Config

javah生成的内容是错误的,因为JNI会在查找内部类_00024的{​​{1}}表示时抛出错误。 $的男人似乎并不暗示任何纠正此事的设定。这只是javah的限制吗?

1 个答案:

答案 0 :(得分:3)

看起来,当涉及内部类类型的参数时,JDK中存在(或至少不一致)的错误。

以下是重现问题的示例类:

public class A {

    public native void a(android.graphics.Bitmap.Config b);
    public native void a(android.graphics.Bitmap.Config b, int c);
    static {
        System.loadLibrary("hello-libs");
        a(null);
    }
}

如果您使用javah生成本机标头,则会获得

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_hellolibs_MainActivity */

#ifndef _Included_com_example_hellolibs_MainActivity
#define _Included_com_example_hellolibs_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     A
 * Method:    a
 * Signature: (Landroid/graphics/Bitmap/Config;)V
 */
JNIEXPORT void JNICALL A_a__Landroid_graphics_Bitmap_Config_2
  (JNIEnv *, jobject, jobject);

/*
 * Class:     A
 * Method:    a
 * Signature: (Landroid/graphics/Bitmap/Config;I)V
 */
JNIEXPORT void JNICALL Java_A_a__Landroid_graphics_Bitmap_Config_2I
  (JNIEnv *, jobject, jobject, jint);

#ifdef __cplusplus
}
#endif
#endif

和 -

  

java.lang.UnsatisfiedLinkError:找不到void A.a的实现(android.graphics.Bitmap $ Config)(试过Java_A_a和Java_A_a__Landroid_graphics_Bitmap_00024Config_2)

但是这个错误很少会影响javahjavac -h dir生成的标头,因为通常使用“短”&#39;生成本机方法。名称,例如Java_A_a,它不关心参数的类型。

解决方案是手动更改方法签名,如https://bugs.openjdk.java.net/browse/JDK-8145897中所述。