使用JNI从C ++调用JAVA方法,无参数 [英] Calling a JAVA method from C++ with JNI, no parameters

查看:474
本文介绍了使用JNI从C ++调用JAVA方法,无参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请与我一起,我是一个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.

推荐答案

很多事情...


  1. 给定声明 JNIEnv * env; ,并且假设您使用的是C ++,则使用 env-> FindClass(s​​omeString)如何做。如果是C,你会使用 FindClass(env,someString),但在C ++中你使用 env-> FindClass(s​​omeString)

  2. FindClass 中使用的字符串是完全限定路径名,但 / 作为分隔符,而不是例如,如果类 Foo c $ c> bar.baz.quux ,完全限定名称是 bar.baz.quux.Foo 和你给的字符串到 FindClass bar / baz / quux / Foo

  3. 只有每个C ++进程创建一个JVM。我很确定你需要创建一个单一的JVM一次。因此,您需要将 JavaVM * vm 作为一个全局变量(或者至少在需要使用的地方可以访问)。与线程相同的C ++线程中的所有内容调用 JNI_CreateJavaVM()将使用由该调用填充的 JNIEnv * 使用JVM需要调用 AttachCurrentThread ,它会将该线程绑定到JVM并填写 new JNIEnv * 对于该线程有效。

  4. 您仔细检查了编译器/ IDE设置,以确保 JDK_HOME / include c>目录(其中包含 jni.h )在包含搜索路径中? JDK_HOME / include / android 目录(或者在Android JDK中调用 JDK_HOME / include 中的操作特定目录)?

  1. Given the declaration JNIEnv* env;, and given that you're in C++, you use it as env->FindClass(someString), not how you're doing it. If it was C you'd use FindClass(env, someString) but in C++ you use env->FindClass(someString).
  2. The string to use in FindClass is the fully qualified path name but with / as the delimiter instead of . For example, if the class is Foo in package bar.baz.quux, the fully-qualified name is bar.baz.quux.Foo and the string you'd give to FindClass is bar/baz/quux/Foo.
  3. 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 called JNI_CreateJavaVM() will use the JNIEnv * that gets filled in by that call. Every other thread that wants to use the JVM needs to call AttachCurrentThread which will bind that thread to the JVM and fill in a new JNIEnv * valid for that thread.
  4. Have you double-checked your compiler/IDE settings to make sure that the JDK_HOME/include directory (which contains jni.h) is in the includes search path? Same for the JDK_HOME/include/android directory (or whatever the operating specific directory in JDK_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆