我无法从我的本机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]
答案 0 :(得分:1)
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);