Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JNI on Android: How to retrieve a string from Java code?

I read a lot of examples to retrieve a java string in C/C++ code, but it seems that I miss something. this simple code doesn't work..

In ActivityTest (android java code) I've:

public static native void nativeInit(String stringfromjava);

In TestActivity I've:

ActivityTest.nativeInit("test");

and in my test-jni.c:

JNIEXPORT void JNICALL  Java_com_test_jni_ActivityTest_nativeInit(JNIEnv* env, jclass cls, jobject obj, jstring stringfromjava){

__android_log_print(ANDROID_LOG_INFO, "TESTJNI","Native Init started");

const char* w_buf = (*env)->GetStringUTFChars(env, stringfromjava, 0);

if(w_buf == NULL) {
    __android_log_print(ANDROID_LOG_INFO, "TESTJNI","file path recv nothing");
}

else {
        __android_log_print(ANDROID_LOG_INFO, "TESTJNI","String: %s", w_buf);
}

(*env)->ReleaseStringUTFChars(env, stringfromjava, w_buf);

}

But in my logcat I get only:

I/TESTJNI (18921): Native Init started
I/TESTJNI (18921): String: 

Where I'm wrong...?

FIXED Thanks to Mario, removing "jobject obj" from the signature fixed my issue!

like image 205
Giuseppe Avatar asked Oct 08 '22 20:10

Giuseppe


1 Answers

Only wrote one short test so far (similar to your program), but my function had a bit different signature (might depend on SDK/NDK/JDK version? took it from some tutorial code I found):

extern "C" void Java_com_whatever_Activity_method(JNIEnv* env, jobject jthis, jstring param);

Obviously you won't need extern "C" if you're not writing C++.

The Java signature would be:

native void method(String param);

Edit:

To obtain the string (not sure if this is 100% correct, but it works):

const char *cparam = env->GetStringUTFChars(param, 0);
// .. do something with it
env->ReleaseStringUTFChars(param, cparam);

Open to suggestions in case there's something wrong in there. It works fine, but might still be some issue, so feel free to comment.

like image 129
Mario Avatar answered Oct 11 '22 09:10

Mario