У меня есть функция JNI, которая проходит android.graphics.Bitmap$Config
в качестве аргумента. Config
это внутренний класс Bitmap
, Когда я запускаю javah, я получаю неверную подпись заголовка (усечение только до одного аргумента):
Landroid_graphics_Bitmap_Config
что эквивалентно:
Landroid/graphics/Bitmap/Config
вместо:
Landroid_graphics_Bitmap_00024Config
что эквивалентно
Landroid/graphics/Bitmap$Config
То, что генерирует javah, неверно, так как JNI выдаст ошибку, ища _00024
представление $
для внутреннего класса. Человек для javah
кажется, не подразумевает каких-либо настроек, чтобы исправить это. Это просто ограничение javah
?
Похоже, есть ошибка (или несоответствие, по крайней мере) в 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)
Но эта ошибка редко влияет на заголовки, сгенерированные javah
или же javac -h dir
потому что обычно нативные методы генерируются с «короткими» именами, например Java_A_a
который не заботится о типе параметра.
Решение состоит в том, чтобы вручную изменить сигнатуры метода, как предлагается в https://bugs.openjdk.java.net/browse/JDK-8145897.
Других решений пока нет …