使用JNI从C ++调用JAVA方法,无参数 [英] Calling a JAVA method from C++ with JNI, no parameters
问题描述
请与我一起,我是一个iPhone开发人员,这整个android这让我困惑了一下。
Please bear with me, I am an iPhone developer and this whole android this confuses me a bit.
我有一些c ++方法从cocos2d-x CCMenuItem调用。因此我不能发送任何参数,根据文档。
I have some c++ methods that are called from a cocos2d-x CCMenuItem. Therefore I cannot send any parameters, according to the docs.
我需要使用Android浏览器打开一个URL,这将需要我调用一个JAVA函数来启动一个新的意图。
I need to open a url with the android browser which will require me to call a JAVA function to start a new intent.
我知道我需要创建一个虚拟机,但是下面的代码给我的错误:
I understand that I need to create a VM, however the below code gives me the error:
jni / /../Classes/OptionsScene.cpp:184:error:'JNI_CreateJavaVM'is
未在此范围内声明
jni/../../Classes/OptionsScene.cpp:184: error: 'JNI_CreateJavaVM' was not declared in this scope
我在看这个线程:从Android的C ++调用java方法
但他使用参数,我不能这样做。我不知道他们的代码中的那些是只是让他们自己。
But he uses parameters, and I can't do that. And I don't see where those are in his code to just make them myself.
我不知道什么字符串应该在查找类方法。
另外,我认为在每个需要调用的方法中创建一个新的VM实例是相当可怕的。我如何创建一个单身人士使用全面?
I don't know what the string should be in the 'Find Class' method. Also, I assume it is pretty terrible to create a new VM instance in every method I need to call. How would I create one as a singleton to use across the board?
这是我的菜单项调用的c ++代码:
This is my c++ code called 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();
这是我需要调用的JAVA方法:
And this is the JAVA Method that 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.
推荐答案
很多事情...
- 给定声明
JNIEnv * env;
,并且假设您使用的是C ++,则使用env-> FindClass(someString)
,不如何做。如果是C,你会使用FindClass(env,someString)
,但在C ++中你使用env-> FindClass(someString)
-
FindClass
中使用的字符串是完全限定路径名,但/
作为分隔符,而不是。
例如,如果类Foo
c $ c> bar.baz.quux ,完全限定名称是bar.baz.quux.Foo
和你给的字符串到FindClass
是bar / baz / quux / Foo
。 - 只有每个C ++进程创建一个JVM。我很确定你需要创建一个单一的JVM一次。因此,您需要将
JavaVM * vm
作为一个全局变量(或者至少在需要使用的地方可以访问)。与线程相同的C ++线程中的所有内容调用JNI_CreateJavaVM()
将使用由该调用填充的JNIEnv *
使用JVM需要调用AttachCurrentThread
,它会将该线程绑定到JVM并填写 newJNIEnv *
对于该线程有效。 - 您仔细检查了编译器/ IDE设置,以确保
JDK_HOME / include
c>目录(其中包含jni.h
)在包含搜索路径中?JDK_HOME / include / android
目录(或者在Android JDK中调用JDK_HOME / include
中的操作特定目录)?
- Given the declaration
JNIEnv* env;
, and given that you're in C++, you use it asenv->FindClass(someString)
, not how you're doing it. If it was C you'd useFindClass(env, someString)
but in C++ you useenv->FindClass(someString)
. - The string to use in
FindClass
is the fully qualified path name but with/
as the delimiter instead of.
For example, if the class isFoo
in packagebar.baz.quux
, the fully-qualified name isbar.baz.quux.Foo
and the string you'd give toFindClass
isbar/baz/quux/Foo
. - You can only create one JVM per C++ process. I'm pretty sure you need to create a single JVM one time. You will therefore need to have the
JavaVM* vm
be a global variable (or at least be somewhere accessible to everything that needs to use. Everything in the same C++ thread as the thread that calledJNI_CreateJavaVM()
will use theJNIEnv *
that gets filled in by that call. Every other thread that wants to use the JVM needs to callAttachCurrentThread
which will bind that thread to the JVM and fill in a newJNIEnv *
valid for that thread. - Have you double-checked your compiler/IDE settings to make sure that the
JDK_HOME/include
directory (which containsjni.h
) is in the includes search path? Same for theJDK_HOME/include/android
directory (or whatever the operating specific directory inJDK_HOME/include
is called in a Android JDK)?
一个非常有用的资源是 JNI书< a>
A very useful resource is The JNI book
但是在阅读它时要小心,因为一些例子是在C中,有些是在C ++中,所以确保你理解调用约定是如何不同的。
But be careful while reading it because some examples are in C and some are in C++, so make sure you understand how the calling conventions differ.
这篇关于使用JNI从C ++调用JAVA方法,无参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!