java Android ndk:使用jni从c ++调用Java方法的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6584269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 16:28:43  来源:igfitidea点击:

Android ndk : Problem for call of Java method from c++ with jni

javac++androidjava-native-interfaceandroid-ndk

提问by Crisic

I try to work on Android NDK, my first test are not very conclusive, I need for help because I don't see where is my error.

我尝试在 Android NDK 上工作,我的第一次测试不是很确定,我需要帮助,因为我看不到我的错误在哪里。

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.

下面的代码编译没有问题,但是当在模拟器上运行时,程序返回 SIGSEGV 信号并且在 logcat 中没有明确写入错误。但是,会出现指示未找到 Java 类的警告。经过一天对这个问题的研究,一切看起来都是正确的。

Here is my Java code: JNITestActivity.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 ;
    }

}

Here is my C++ code: testjni.cpp

这是我的 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);
}

And here is my Makefile: Android.mk

这是我的 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 :

和 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.access00(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.

谢谢你,克里斯托夫。

采纳答案by Crisic

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...

该函数javaCallJNI()在 Java 中被声明为静态本机,但是,静态方法不能调用非静态方法......

For resolve this problem, just replace :

为了解决这个问题,只需更换:

public static native void javaCallJNI();

by

经过

public native void javaCallJNI();

in JNITestActivity.java

在 JNITestActivity.java 中

Thank for your help and see soon ;)

感谢您的帮助,很快就会看到;)

回答by Maximus

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);