Android ndk : Problem for call of Java method from c++ with jni
I try to work on Android NDK, my first test are not very conclusive, I need f开发者_开发技巧or help because I don't see where is my error.
The following code compiles without problem but when is running on the emulator, the program returns SIGSEGV signal and no error is explicitly written in the logcat. however, a warning indicating that the Java class is not found appears. After a day of research on this problem, everything looks correct.
Here is my Java code: 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 ;
}
}
Here is my C++ code: 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);
}
And here is my 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)
And the logcat error :
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.
Thank you, Christophe.
After one day lost due to this bug, i finally found the solution of my problem :
The function javaCallJNI()
is declared as a static native in Java, but, a static method can't call a non static method...
For resolve this problem, just replace :
public static native void javaCallJNI();
by
public native void javaCallJNI();
in JNITestActivity.java
Thank for your help and see soon ;)
What you have looks okay to me... but you might try replacing
jclass clazz = env->FindClass("com/test/jnitest/JNITestActivity");
With
jclass clazz = env->GetObjectClass(obj);
精彩评论