在Android Class ID&amp ;;中调用c ++中的java方法方法ID

时间:2016-08-15 16:14:02

标签: java android c java-native-interface adb

我无法从我的本机C代码调用Java。具体来说,我很难确保获得正确的类和方法ID。我最初对静态方法有一些好运,而不是成员函数,但我已经尝试了两种方法。

如下所示,简单的Java布尔函数retTrue成功返回,但我似乎无法正确传递数据数组。

static jmethodID midSetRTS,midClearRTS,midClearRTSb,midTX,midSniffRx,midSniffTx,midClose;     static jmethodID midgetFTDIDevice;

static JavaVM *g_VM;
static jclass cls;
static jmethodID javaMethodRef;


JNIEXPORT jstring JNICALL Java_com_example_rick_myjni_MyNDK_getMyString(JNIEnv *env, jobject jobj) {
    __android_log_print(ANDROID_LOG_VERBOSE, TAG, "Hello from native code");

    env->GetJavaVM(&g_VM);
    __android_log_print(ANDROID_LOG_VERBOSE, TAG, "Attaching to VM thread.");

    jint rs = g_VM->AttachCurrentThread((JNIEnv**)&env,NULL);
    if(rs == JNI_OK)
        __android_log_print(ANDROID_LOG_VERBOSE, TAG, "Attached");
    else
        __android_log_print(ANDROID_LOG_VERBOSE, TAG, "Failed to Attach");

    static int once = 1;
    if (once) {
        jclass dataClass = env->FindClass("com/example/rick/myjni/MainActivity");
        if (env->ExceptionCheck()) {
           return (*env).NewStringUTF("Exception");
        }

        cls = (jclass) env->NewGlobalRef(dataClass);
        if (env->ExceptionCheck()) {
           return (*env).NewStringUTF("Exception");
        }

        javaMethodRef = env->GetStaticMethodID(cls, "retTrue", "()Z");
        __android_log_print(ANDROID_LOG_VERBOSE, TAG, "cls: %d javaMethodRef %d", (int)cls, (int)javaMethodRef);
        midTX = env->GetStaticMethodID(cls, "TX", "([BI)Z");
        __android_log_print(ANDROID_LOG_VERBOSE, TAG, "cls: %d midTX %d", (int)cls, (int)midTX);

        if (env->ExceptionCheck()) {
           return (*env).NewStringUTF("Exception");
        }
        once = 0;
    }
    bool success = true;
    jbyte txTestMsg[] = {0x18, 0x00, 0x0D, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0xFF,0x00,0xFF};
    jint len = 16;
    __android_log_print(ANDROID_LOG_VERBOSE, TAG, "len: %d txTestMsg: %x %x %x %x  %x %x %x %x  %x %x %x %x  %x %x %x %x ", len,
        txTestMsg[0], txTestMsg[1], txTestMsg[2], txTestMsg[3],
        txTestMsg[4], txTestMsg[5], txTestMsg[6], txTestMsg[7],
        txTestMsg[8], txTestMsg[9], txTestMsg[10], txTestMsg[11],
        txTestMsg[12], txTestMsg[13], txTestMsg[14], txTestMsg[15]);

    success = env->CallStaticBooleanMethod(cls, javaMethodRef);
    __android_log_print(ANDROID_LOG_VERBOSE, TAG, "Call retTrue succces: %d",success);

    COFFEE_TRY() {
        success = env->CallStaticBooleanMethod(cls, midTX, txTestMsg, len);
        if (env->ExceptionCheck()) {
               return (*env).NewStringUTF("Exception");
        }
    }
    COFFEE_CATCH() {
        coffeecatch_throw_exception(env);
    } COFFEE_END();

    if(success)
        return (*env).NewStringUTF("Success");
    else
        return (*env).NewStringUTF("Failure");
}

来自主要活动

 public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    ...

    public static boolean TX(byte[] data, int len)
    {
        Log.i(TAG,"MainActivity:TX length " + len + " data: " + data.toString() );
        return myFTDIdevice.TX(data,len);
    }

    public static boolean retTrue()
    {
        Log.i(TAG,"MainActivity:reTrue");
        return true;
    }

注意android日志文件的输出:

08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: Hello from native code
08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: Attaching to VM thread.
08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: Attached
08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: cls: 1050382 javaMethodRef -2012626856
08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: cls: 1050382 midTX -2012627024
08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: len: 16 txTestMsg: 18 0 d 1  2 3 4 5  6 7 8 9  a ffffffff 0 ffffffff 
08-17 14:55:49.827 12389-12432/com.example.rick.myjni I/MainActivity: MainActivity:reTrue
08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: Call retTrue succces: 1
08-17 14:55:49.832 12389-12432/com.example.rick.myjni A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdead4321 in tid 12432 (Thread-9233)
08-17 14:55:49.872 12389-12396/com.example.rick.myjni W/art: Suspending all threads took: 13.880ms
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: JNI NewStringUTF called with pending exception 'java.lang.Error' thrown in java.lang.String com.example.rick.myjni.MyNDK.getMyString():-2
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]     in call to NewStringUTF
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]     from java.lang.String com.example.rick.myjni.MyNDK.getMyString()
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] "Thread-9233" prio=5 tid=16 Runnable
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   | group="main" sCount=0 dsCount=0 obj=0x12f7f7c0 self=0xb47c4800
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   | sysTid=12432 nice=0 cgrp=default sched=0/0 handle=0xb4509c00
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   | state=R schedstat=( 0 0 0 ) utm=6 stm=5 core=1 HZ=100
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   | stack=0x9ce0c000-0x9ce0e000 stackSize=1036KB
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   | held mutexes= "mutator lock"(shared held)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   native: #00 pc 00004e6c  /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   native: #01 pc 00003665  /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   native: #02 pc 00266509  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+84)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   native: #03 pc 0024857f  /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+158)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   native: #04 pc 000b4e83  /system/lib/libart.so (art::JniAbort(char const*, char const*)+610)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   native: #05 pc 000b55a9  /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+68)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   native: #06 pc 000b8873  /system/lib/libart.so (art::ScopedCheck::ScopedCheck(_JNIEnv*, int, char const*)+1342)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   native: #07 pc 000c1665  /system/lib/libart.so (art::CheckJNI::NewStringUTF(_JNIEnv*, char const*)+28)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   native: #08 pc 0000162f  /data/app/com.example.rick.myjni-2/lib/arm/libMyLibrary.so (_JNIEnv::NewStringUTF(char const*)+10)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   native: #09 pc 00001845  /data/app/com.example.rick.myjni-2/lib/arm/libMyLibrary.so (Java_com_example_rick_myjni_MyNDK_getMyString+516)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   native: #10 pc 000162e7  /data/data/com.example.rick.myjni/cache/slice-slice_5-classes.dex (Java_com_example_rick_myjni_MyNDK_getMyString__+82)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   at com.example.rick.myjni.MyNDK.getMyString(Native method)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   at com.example.rick.myjni.MainActivity$3.run(MainActivity.java:150)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]   at java.lang.Thread.run(Thread.java:818)
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] 

1 个答案:

答案 0 :(得分:1)

OMG我想把我的脑袋弄出来。它与方法ID或类ID无关,但传递的参数无关。我必须在C中实例化一个有效的java数组,以便它可以传递。

   bool success = true;
    jbyte temptxTestMsg[] = {0x18, 0x00, 0x0D, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0xFF,0x00,0xFF};
    jint len = 16;

    jbyteArray txTestMsg = env->NewByteArray(len);
    env->SetByteArrayRegion(txTestMsg,0,len,temptxTestMsg);