Call JAVA method from C ++ with JNI, without parameters

Please carry me, I'm an iPhone developer, and this whole android bothers me a bit.

I have some C ++ methods that are called from cocos2d-x CCMenuItem. Therefore, I can not send any parameters according to the docs.

I need to open a URL with an Android browser that will require me to call the JAVA function in order to start a new intent.

I understand that I need to create a virtual machine, however the code below gives me an error:

jni /../../ Classes / ParametersScene.cpp: 184: error: 'JNI_CreateJavaVM' was not declared in this area

I watched this topic: Calling a java method from C ++ in Android

But it uses parameters, and I cannot do this. And I donโ€™t see where they are in his code, just to make them yourself.

I donโ€™t know what line should be in the Find Class method. Also, I suppose it's pretty terrible to create a new instance of a virtual machine in every method that I need to call. How can I create one singleton for use in all directions?

This is my C ++ code invoked by my menu item:

#include <jni.h> ... JavaVM *vm; // Global ... void OptionsScene::website(){ JNIEnv *env; JavaVMInitArgs vm_args; vm_args.version = JNI_VERSION_1_2; vm_args.nOptions = 0; vm_args.ignoreUnrecognized = 1; jint result = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args); // This line still errors jclass clazz = env->FindClass("com/prndl/project/WebExecute"); jmethodID method = env->GetMethodID(clazz, "website", "(Ljava/lang/String;)V"); env->CallVoidMethod(NULL,method); vm->DestroyJavaVM(); 

And this is the JAVA method I need to call:

 public class WebExecute extends Activity{ public void website(){ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com")); startActivity(browserIntent); } } 

Honestly, I am struggling with this, any help is appreciated. Thanks.

+4
source share
2 answers

A few things...

  • Given the declaration of JNIEnv* env; and given that you are in C ++, you use it as env->FindClass(someString) , not, as you do. If it were C, you would use FindClass(env, someString) , but in C ++ you use env->FindClass(someString) .
  • The string used in FindClass is the full path name, but with / as a separator instead . For example, if the class Foo in the package bar.baz.quux , then the fully qualified name is bar.baz.quux.Foo , and the line you give FindClass will be bar/baz/quux/Foo .
  • You can create only one JVM for a C ++ process. I am sure you need to create a single JVM once. So you will need to have a JavaVM* vm global variable (or at least be available somewhere for everything you need to use. Everything in the same C ++ stream as the stream called JNI_CreateJavaVM() will use JNIEnv * that gets populated with this call Every other thread that wants to use the JVM must call AttachCurrentThread , which will associate this thread with the JVM and populate the new JNIEnv * valid for that thread.
  • Have you double checked your compiler / IDE options to make sure the JDK_HOME/include directory (which contains jni.h ) is in the include search path? Same thing for the JDK_HOME/include/android directory (or any particular directory in the JDK_HOME/include ) in the Android JDK)?

A very useful resource is the JNI Book

But be careful reading it, because some examples are in C and some in C ++, so make sure you understand how calling conventions differ.

+1
source

If you are looking at calling a java method that takes no arguments, the format is jmethodID mid = env->GetStaticMethodID(myClass, "myMethod", "()V");

() Is, as you say, it does not take any parameters.

V says it returns void. Ljava/lang/String; should be used if the method returns an object of type String .

0
source

All Articles