Android ndk: Problema para la llamada del método Java desde c ++ con jni

Trato de trabajar en Android NDK, mi primera prueba no son muy concluyentes, necesito ayuda porque no veo dónde está mi error.

El código siguiente se compila sin problema pero cuando se ejecuta en el emulador, el programa devuelve la señal SIGSEGV y no se escribe explícitamente ningún error en el logcat. Sin embargo, aparece una advertencia que indica que la clase Java no se encuentra. Después de un día de investigación sobre este problema, todo parece correcto.

Aquí está mi código Java: JNITestActivity.java

package com.test.jnitest; import android.app.Activity; import android.os.Bundle; import android.util.Log; public class JNITestActivity extends Activity { private static String LIB_NAME = "JNItest"; static { System.loadLibrary(LIB_NAME); } public static native void javaCallJNI(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.i("onCreate", "Native function begining"); javaCallJNI(); Log.i("onCreate", "Native function ending"); } void callFromCPP() { Log.i("callFromCPP", "JNI can call JAVA !"); return ; } } 

Aquí está mi código C ++: testjni.cpp

 #include <jni.h> #include <android/log.h> #define LOG_TAG "testjni" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) extern "C" { JNIEXPORT void JNICALL Java_com_test_jnitest_JNITestActivity_javaCallJNI(JNIEnv* env, jobject obj); }; jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env; if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) return -1; LOGI("JNI INIT"); return JNI_VERSION_1_6; } JNIEXPORT void JNICALL Java_com_test_jnitest_JNITestActivity_javaCallJNI(JNIEnv* env, jobject obj) { LOGI("JNI work !"); jclass clazz = env->FindClass("com/test/jnitest/JNITestActivity"); if (clazz == 0) { LOGI("FindClass error"); return; } jmethodID javamethod = env->GetMethodID(clazz, "callFromCPP", "()V"); if (javamethod == 0) { LOGI("GetMethodID error"); return; } env->CallVoidMethod(obj, javamethod); } 

Y aquí está mi Makefile: Android.mk

 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libJNItest LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog LOCAL_SRC_FILES := \ src/testjni.cpp include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) 

Y el error logcat:

 INFO/testjni(9387): JNI INIT 07-05 15:35:16.993: INFO/onCreate(9387): Native function begining 07-05 15:35:16.993: INFO/testjni(9387): JNI work ! 07-05 15:35:17.003: WARN/dalvikvm(9387): JNI WARNING: can't call Lcom/test/jnitest/JNITestActivity;.callFromCPP on instance of Ljava/lang/Class; 07-05 15:35:17.003: INFO/dalvikvm(9387): "main" prio=5 tid=1 RUNNABLE 07-05 15:35:17.018: INFO/dalvikvm(9387): | group="main" sCount=0 dsCount=0 obj=0x4001f1a8 self=0xce48 07-05 15:35:17.018: INFO/dalvikvm(9387): | sysTid=9387 nice=0 sched=0/0 cgrp=default handle=-1345006528 07-05 15:35:17.023: INFO/dalvikvm(9387): | schedstat=( 219631994 557413541 53 ) 07-05 15:35:17.023: INFO/dalvikvm(9387): at com.test.jnitest.JNITestActivity.javaCallJNI(Native Method) 07-05 15:35:17.023: INFO/dalvikvm(9387): at com.test.jnitest.JNITestActivity.onCreate(JNITestActivity.java:23) 07-05 15:35:17.023: INFO/dalvikvm(9387): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 07-05 15:35:17.048: INFO/dalvikvm(9387): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) 07-05 15:35:17.053: INFO/dalvikvm(9387): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) 07-05 15:35:17.053: INFO/dalvikvm(9387): at android.app.ActivityThread.access$1500(ActivityThread.java:117) 07-05 15:35:17.053: INFO/dalvikvm(9387): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 07-05 15:35:17.053: INFO/dalvikvm(9387): at android.os.Handler.dispatchMessage(Handler.java:99) 07-05 15:35:17.053: INFO/dalvikvm(9387): at android.os.Looper.loop(Looper.java:123) 07-05 15:35:17.053: INFO/dalvikvm(9387): at android.app.ActivityThread.main(ActivityThread.java:3683) 07-05 15:35:17.053: INFO/dalvikvm(9387): at java.lang.reflect.Method.invokeNative(Native Method) 07-05 15:35:17.053: INFO/dalvikvm(9387): at java.lang.reflect.Method.invoke(Method.java:507) 07-05 15:35:17.053: INFO/dalvikvm(9387): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 07-05 15:35:17.053: INFO/dalvikvm(9387): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 07-05 15:35:17.053: INFO/dalvikvm(9387): at dalvik.system.NativeStart.main(Native Method) 07-05 15:35:17.053: ERROR/dalvikvm(9387): VM aborting 07-05 15:35:17.163: INFO/DEBUG(31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 07-05 15:35:17.163: INFO/DEBUG(31): Build fingerprint: 'generic/sdk/generic:2.3.3/GRI34/101070:eng/test-keys' 07-05 15:35:17.163: INFO/DEBUG(31): pid: 9387, tid: 9387 >>> com.test.jnitest <<< 07-05 15:35:17.173: INFO/DEBUG(31): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadd00d 07-05 15:35:17.173: INFO/DEBUG(31): r0 fffffec4 r1 deadd00d r2 00000026 r3 00000000 07-05 15:35:17.183: INFO/DEBUG(31): r4 800a45c0 r5 40517438 r6 41ad8ad0 r7 40517438 07-05 15:35:17.183: INFO/DEBUG(31): r8 befc3428 r9 418fccdc 10 418fccc8 fp 42598bb8 07-05 15:35:17.193: INFO/DEBUG(31): ip 800a4720 sp befc3398 lr afd19375 pc 80045a4a cpsr 20000030 07-05 15:35:17.453: INFO/DEBUG(31): #00 pc 00045a4a /system/lib/libdvm.so 07-05 15:35:17.453: INFO/DEBUG(31): #01 pc 00037748 /system/lib/libdvm.so 07-05 15:35:17.463: INFO/DEBUG(31): #02 pc 0003dc44 /system/lib/libdvm.so 07-05 15:35:17.473: INFO/DEBUG(31): #03 pc 0003fa9c /system/lib/libdvm.so 07-05 15:35:17.473: INFO/DEBUG(31): #04 pc 000003f2 /data/data/com.test.jnitest/lib/libJNItest.so 07-05 15:35:17.473: INFO/DEBUG(31): #05 pc 00000440 /data/data/com.test.jnitest/lib/libJNItest.so 07-05 15:35:17.473: INFO/DEBUG(31): #06 pc 00017d74 /system/lib/libdvm.so 07-05 15:35:17.483: INFO/DEBUG(31): #07 pc 00048ecc /system/lib/libdvm.so 07-05 15:35:17.493: INFO/DEBUG(31): #08 pc 00041a86 /system/lib/libdvm.so 07-05 15:35:17.493: INFO/DEBUG(31): #09 pc 0004e624 /system/lib/libdvm.so 07-05 15:35:17.503: INFO/DEBUG(31): #10 pc 0001cfd4 /system/lib/libdvm.so 07-05 15:35:17.503: INFO/DEBUG(31): #11 pc 000220dc /system/lib/libdvm.so 07-05 15:35:17.503: INFO/DEBUG(31): #12 pc 00020fd0 /system/lib/libdvm.so 07-05 15:35:17.523: INFO/DEBUG(31): #13 pc 0005f5de /system/lib/libdvm.so 07-05 15:35:17.523: INFO/DEBUG(31): #14 pc 00066fce /system/lib/libdvm.so 07-05 15:35:17.523: INFO/DEBUG(31): #15 pc 0001cfd4 /system/lib/libdvm.so 07-05 15:35:17.533: INFO/DEBUG(31): #16 pc 000220dc /system/lib/libdvm.so 07-05 15:35:17.543: INFO/DEBUG(31): #17 pc 00020fd0 /system/lib/libdvm.so 07-05 15:35:17.543: INFO/DEBUG(31): #18 pc 0005f430 /system/lib/libdvm.so 07-05 15:35:17.553: INFO/DEBUG(31): #19 pc 0004b9a8 /system/lib/libdvm.so 07-05 15:35:17.553: INFO/DEBUG(31): #20 pc 0003ebb0 /system/lib/libdvm.so 07-05 15:35:17.563: INFO/DEBUG(31): #21 pc 000314ac /system/lib/libandroid_runtime.so 07-05 15:35:17.573: INFO/DEBUG(31): #22 pc 000322c6 /system/lib/libandroid_runtime.so 07-05 15:35:17.573: INFO/DEBUG(31): #23 pc 00008ca2 /system/bin/app_process 07-05 15:35:17.573: INFO/DEBUG(31): #24 pc 00014db8 /system/lib/libc.so 07-05 15:35:17.573: INFO/DEBUG(31): code around pc: 07-05 15:35:17.583: INFO/DEBUG(31): 80045a28 447a4479 ed0cf7d1 20004c09 ee34f7d1 07-05 15:35:17.583: INFO/DEBUG(31): 80045a38 447c4808 6bdb5823 d0002b00 49064798 07-05 15:35:17.593: INFO/DEBUG(31): 80045a48 700a2226 eea0f7d1 000436b7 00045275 07-05 15:35:17.593: INFO/DEBUG(31): 80045a58 0005eb82 fffffec4 deadd00d b510b40e 07-05 15:35:17.604: INFO/DEBUG(31): 80045a68 4c0a4b09 447bb083 aa05591b 6b5bca02 07-05 15:35:17.604: INFO/DEBUG(31): code around lr: 07-05 15:35:17.633: INFO/DEBUG(31): afd19354 b0834a0d 589c447b 26009001 686768a5 07-05 15:35:17.633: INFO/DEBUG(31): afd19364 220ce008 2b005eab 1c28d003 47889901 07-05 15:35:17.633: INFO/DEBUG(31): afd19374 35544306 d5f43f01 2c006824 b003d1ee 07-05 15:35:17.633: INFO/DEBUG(31): afd19384 bdf01c30 000281a8 ffffff88 1c0fb5f0 07-05 15:35:17.643: INFO/DEBUG(31): afd19394 43551c3d a904b087 1c16ac01 604d9004 07-05 15:35:17.643: INFO/DEBUG(31): stack: 07-05 15:35:17.643: INFO/DEBUG(31): befc3358 00000015 07-05 15:35:17.643: INFO/DEBUG(31): befc335c afd18407 /system/lib/libc.so 07-05 15:35:17.653: INFO/DEBUG(31): befc3360 afd4270c /system/lib/libc.so 07-05 15:35:17.653: INFO/DEBUG(31): befc3364 afd426b8 /system/lib/libc.so 07-05 15:35:17.653: INFO/DEBUG(31): befc3368 00000000 07-05 15:35:17.653: INFO/DEBUG(31): befc336c afd19375 /system/lib/libc.so 07-05 15:35:17.653: INFO/DEBUG(31): befc3370 0000ce48 [heap] 07-05 15:35:17.663: INFO/DEBUG(31): befc3374 afd183d9 /system/lib/libc.so 07-05 15:35:17.663: INFO/DEBUG(31): befc3378 40517438 /dev/ashmem/dalvik-heap (deleted) 07-05 15:35:17.673: INFO/DEBUG(31): befc337c 0005eb82 [heap] 07-05 15:35:17.673: INFO/DEBUG(31): befc3380 40517438 /dev/ashmem/dalvik-heap (deleted) 07-05 15:35:17.673: INFO/DEBUG(31): befc3384 41ad8ad0 /dev/ashmem/dalvik-LinearAlloc (deleted) 07-05 15:35:17.673: INFO/DEBUG(31): befc3388 40517438 /dev/ashmem/dalvik-heap (deleted) 07-05 15:35:17.673: INFO/DEBUG(31): befc338c afd18437 /system/lib/libc.so 07-05 15:35:17.673: INFO/DEBUG(31): befc3390 df002777 07-05 15:35:17.673: INFO/DEBUG(31): befc3394 e3a070ad 07-05 15:35:17.673: INFO/DEBUG(31): #00 befc3398 40009328 /dev/ashmem/dalvik-heap (deleted) 07-05 15:35:17.683: INFO/DEBUG(31): befc339c 8003774d /system/lib/libdvm.so 07-05 15:35:17.683: INFO/DEBUG(31): #01 befc33a0 40009328 /dev/ashmem/dalvik-heap (deleted) 07-05 15:35:17.693: INFO/DEBUG(31): befc33a4 8003dc49 /system/lib/libdvm.so 07-05 15:35:19.693: DEBUG/Zygote(33): Process 9387 terminated by signal (11) 07-05 15:35:19.713: INFO/ActivityManager(74): Process com.test.jnitest (pid 9387) has died. 

Gracias, Christophe.

Después de un día perdido debido a este error, finalmente encontré la solución de mi problema:

La función javaCallJNI() se declara como un nativo estático en Java, pero, un método estático no puede llamar a un método no estático …

Para resolver este problema, reemplace:

 public static native void javaCallJNI(); 

por

 public native void javaCallJNI(); 

En JNITestActivity.java

Gracias por su ayuda y ver pronto;)

Lo que tienes parece bien para mí … pero puedes intentar reemplazar

 jclass clazz = env->FindClass("com/test/jnitest/JNITestActivity"); 

Con

 jclass clazz = env->GetObjectClass(obj); 
  • Java: acceso al campo final estático en JNI
  • Callback Listener en Unity - Cómo llamar al método de archivo de script desde UnityPlayerActivity en Android
  • Suma de dos valores usando ndk android
  • Señal fatal 11 (SIGSEGV)
  • ¿Cómo utilizar Java con NDK Android?
  • SQLite con Android NDK
  • Depuración del código Android NDK C / C ++ en Eclipse: los puntos de interrupción no se alcanzan
  • Jni llama al método java que toma una interfaz java personalizada como parámetro
  • Java.lang.UnsatisfiedLinkError: No se ha encontrado ninguna implementación para Boolean
  • Cómo utilizar correctamente NDK-Build en Android Studio 2.2 Vista previa 1
  • Rendimiento de Android NDK sobre el código Java habitual
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.