I'm trying to get a simple Java method call from C++ while Java calls native method. Here's the Java code:
public class MainActivity extends Activity { private static String LIB_NAME = "name"; static { System.loadLibrary(LIB_NAME); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView tv = (TextView) findViewById(R.id.textview); tv.setText(this.getJniString()); } public void messageMe(String text) { System.out.println(text); } public native String getJniString(); }
I'm trying to call messageMe
method from native code in the process of getJniString*
method call from Java to native.
native.cpp:
#include <string.h> #include <stdio.h> #include <jni.h> jstring Java_the_package_MainActivity_getJniString( JNIEnv* env, jobject obj, jint depth ){ // JavaVM *vm; // JNIEnv *env; // JavaVMInitArgs vm_args; // vm_args.version = JNI_VERSION_1_2; // vm_args.nOptions = 0; // vm_args.ignoreUnrecognized = 1; // // // Construct a VM // jint res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args); // Construct a String jstring jstr = env->NewStringUTF("This string comes from JNI"); // First get the class that contains the method you need to call jclass clazz = env->FindClass("the/package/MainActivity"); // Get the method that you want to call jmethodID messageMe = env->GetMethodID(clazz, "messageMe", "(Ljava/lang/String;)V"); // Call the method on the object jobject result = env->CallObjectMethod(jstr, messageMe); // Get a C-style string const char* str = env->GetStringUTFChars((jstring) result, NULL); printf("%s\n", str); // Clean up env->ReleaseStringUTFChars(jstr, str); // // Shutdown the VM. // vm->DestroyJavaVM(); return env->NewStringUTF("Hello from JNI!"); }
After clean compilation app stops with next message:
ERROR/AndroidRuntime(742): FATAL EXCEPTION: main java.lang.NoSuchMethodError: messageMe at *.android.t3d.MainActivity.getJniString(Native Method) at *.android.t3d.MainActivity.onCreate(MainActivity.java:22)
Apparently it means that method name is wrong, but it looks OK to me.
To call a specific Java function from C, you need to do the following: Obtain the class reference using the FindClass(,,) method. Obtain the method IDs of the functions of the class that you want to call using the GetStaticMethodID and GetMethodID function calls.
To call a method in Java, you type the method's name, followed by brackets. This code simply prints “Hello world!” to the screen. Therefore, any time we write helloMethod(); in our code, it will show that message to the screen.
Example# The Java Native Interface (JNI) allows you to call native functions from Java code, and vice versa. This example shows how to load and call a native function via JNI, it does not go into accessing Java methods and fields from native code using JNI functions.
The Android Native Development Kit (NDK): a toolset that allows you to use C and C++ code with Android, and provides platform libraries that allow you to manage native activities and access physical device components, such as sensors and touch input.
If it's an object method, you need to pass the object to CallObjectMethod
:
jobject result = env->CallObjectMethod(obj, messageMe, jstr);
What you were doing was the equivalent of jstr.messageMe()
.
Since your is a void method, you should call:
env->CallVoidMethod(obj, messageMe, jstr);
If you want to return a result, you need to change your JNI signature (the ()V
means a method of void
return type) and also the return type in your Java code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With