Android ndk: проблема для вызова метода Java из c ++ с jni

Я пытаюсь работать над Android NDK, мой первый тест не очень убедителен, мне нужна помощь, потому что я не вижу, где моя ошибка.

Следующий код компилируется без проблем, но когда он запущен на эмуляторе, программа возвращает сигнал SIGSEGV, и никакая ошибка явно не записывается в logcat. Однако появляется предупреждение о том, что класс Java не найден. После дня исследования этой проблемы все выглядит правильно.

Вот мой код 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 ; } } 

Вот мой код на 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); } 

И вот мой 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) 

И ошибка 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. 

Благодарю вас, Кристоф.

Solutions Collecting From Web of "Android ndk: проблема для вызова метода Java из c ++ с jni"

После одного дня, потерянного из-за этой ошибки, я наконец нашел решение своей проблемы:

Функция javaCallJNI() объявлена ​​как статическая нативная в Java, но статический метод не может вызвать нестационарный метод …

Для решения этой проблемы просто замените:

 public static native void javaCallJNI(); 

от

 public native void javaCallJNI(); 

В JNITestActivity.java

Спасибо за вашу помощь и скоро увидим;)

То, что у вас есть, выглядит хорошо … но вы можете попробовать заменить

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

С

 jclass clazz = env->GetObjectClass(obj);