[英]JNI: javah mangles arguments that are inner classes
I have a JNI function that passes android.graphics.Bitmap$Config
as an argument. 我有一个JNI函数,它将
android.graphics.Bitmap$Config
作为参数传递。 Config
is an inner class of Bitmap
. Config
是Bitmap
的内部类。 When I run javah I get the incorrect header signature of (truncating to just the single argument): 当我运行javah时,我得到了不正确的标头签名(截断到单个参数):
Landroid_graphics_Bitmap_Config
which is the equivalent of: 这相当于:
Landroid/graphics/Bitmap/Config
instead of: 代替:
Landroid_graphics_Bitmap_00024Config
which is the equivalent 这相当于
Landroid/graphics/Bitmap$Config
What javah generates is wrong as JNI will throw an error looking for the _00024
representation of the $
for the inner class. javah生成的是错误的,因为JNI将抛出错误,查找内部类的
$
的_00024
表示。 The man for javah
doesn't seem to imply any setting to correct this. javah
的人似乎并不暗示任何设置来纠正这个问题。 Is this just a limitation of javah
? 这只是
javah
的限制吗?
It looks like, there is a bug (or inconsistency, at least) in JDK when parameters of inner class type are involved. 看起来,当涉及内部类类型的参数时,JDK中存在错误
(或至少不一致) 。
Here is a sample class that reproduces the problem: 这是一个重现问题的示例类:
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);
}
}
If you use javah
to generate the native header, you will get 如果您使用
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
and - 而且 -
java.lang.UnsatisfiedLinkError: No implementation found for void Aa(android.graphics.Bitmap$Config) (tried Java_A_a and Java_A_a__Landroid_graphics_Bitmap_00024Config_2)
java.lang.UnsatisfiedLinkError:找不到void Aa的实现(android.graphics.Bitmap $ Config)(试过Java_A_a和Java_A_a__Landroid_graphics_Bitmap_00024Config_2)
But this bug rarely effects the headers generated by javah
or javac -h dir
, because usually the native methods are generated with 'short' names, eg Java_A_a
which does not care about the type of parameter. 但是这个bug很少影响
javah
或javac -h dir
生成的头文件,因为通常本机方法是用'short'名称生成的,例如Java_A_a
,它不关心参数的类型。
The solution is to manually change the method signatures, as suggested in https://bugs.openjdk.java.net/browse/JDK-8145897 . 解决方案是手动更改方法签名,如https://bugs.openjdk.java.net/browse/JDK-8145897中所述 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.