Gaurav
Gaurav

Reputation: 31

Calling Java From C

I am new to JNI and Android NDK, I want to call a Java API from one of my c language thread. While calling the Java method I am getting error:

Can some one guide me, What is the best approach to call Java method from a c thread?

Below Code is giving me, Invalid JNI Reference Error

JavaVM *m_vm;
jobject obj;

JNIEXPORT  jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    m_vm = vm;
    return JNI_VERSION_1_4;

}


int aWorkerThread() {
    JNIEnv      *env;
    jmethodID   mid;

    (*m_vm)->GetEnv(m_vm, (void**) &env, JNI_VERSION_1_4);
    (*m_vm)->AttachCurrentThread(m_vm, &env, NULL); 

    jclass cls      = (*env)->GetObjectClass(env, obj)
    jmethodID mid   = (*env)->GetMethodID(env, cls, "callbackfromNative", "(Ljava/lang/String;)V");

    if (mid == NULL) {
           return -1;  // method not found
    }

    const char *pchar   = "Hello From C layer";
    jstring jStr        = NULL;
    jStr = (*env)->NewStringUTF(env, pchar);
    (*env)->CallVoidMethod(env, obj, mid,jStr); 

    return 0;
}

Setting obj into a Global Variable

void Java_com_my_demo_init(JNIEnv * env, jobject this, jstring logThis)  
 {  
     int nErrorCode;
     jboolean isCopy;  
     const char * szLogThis = (*env)->GetStringUTFChars(env, logThis, &isCopy);  
     __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "FromJava: [%s]", szLogThis); 

     obj = this; /*Lets assign obj here*/

     /*Some other c code here..*/

     (*env)->ReleaseStringUTFChars(env, logThis, szLogThis);  
 }

Error Message:

06-20 13:12:03.239: WARN/dalvikvm(753): JNI WARNING: 0x44e83338 is not a valid JNI reference
06-20 13:12:03.239: WARN/dalvikvm(753):              in Ldalvik/system/NativeStart;.run ()V  (GetObjectClass)

...
06-20 13:12:03.279: ERROR/dalvikvm(753): VM aborting

Upvotes: 2

Views: 2018

Answers (1)

Eric
Eric

Reputation: 843

You've gotten the object class (cls) and the class method (mid) but you don't actually have an instance of the object. It's like having a null object and trying to call one of its methods. You need to set obj using either the JNI call AllocObject or NewObject, which like executing the "new" Java operator on the object. AllocObject is different from NewObject in that the constructor for the object isn't called.

Upvotes: 2

Related Questions