2012-07-04 75 views
4

請耐心等待,我是一名iPhone開發人員,而這整個Android會讓我感到困惑。使用JNI從C++調用JAVA方法,無參數

我有一些從cocos2d-x CCMenuItem調用的C++方法。根據文檔,我無法發送任何參數。

我需要用android瀏覽器打開一個url,這將需要我調用JAVA函數來啓動一個新的intent。

我明白,我需要創建一個虛擬機,但是下面的代碼給我的錯誤:

jni/../../Classes/OptionsScene.cpp:184: error: 'JNI_CreateJavaVM' was not declared in this scope

我一直在尋找這個線程:Calling a java method from c++ in Android

但他使用的參數,我可以不這樣做。我看不出他的代碼中的哪些部分是我自己製作的。

我不知道'Find Class'方法中的字符串應該是什麼。 另外,我認爲在我需要調用的每個方法中創建一個新的VM實例是非常糟糕的。我將如何創建一個作爲一個單獨使用全面使用?

這是我的C++代碼,通過我的菜單項稱爲:

#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方法:

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

老實說,我這一點,任何掙扎幫助表示讚賞。謝謝。

+0

你現在得到哪些錯誤?只是'JNI_CreateJavaVM'或其他人?你是否仔細檢查了你的編譯器/ IDE設置,以確保包含'jni.h'的'JDK_HOME/include'目錄在包含搜索路徑中? JDK_HOME/include/android'目錄(或者JDK_HOME/include'中的特定操作目錄在Android JDK中調用)是一樣的嗎? – QuantumMechanic

+0

您是否收到編譯錯誤? –

回答

1

一些事情......

  1. 鑑於申報JNIEnv* env;,並給予您在C++的時候,你把它作爲env->FindClass(someString)你怎麼做。如果是C,則使用FindClass(env, someString),但在C++中使用env->FindClass(someString)
  2. 在字符串中FindClass使用是完全合格的路徑名,但與/作爲分隔符,而不是.例如,如果該類在包bar.baz.quuxFoo,完全合格的名稱是bar.baz.quux.Foo和字符串你給到FindClassbar/baz/quux/Foo
  3. 您只能爲每個C++進程創建一個JVM。我很肯定你需要一次創建一個JVM。因此,您需要將JavaVM* vm設置爲全局變量(或者至少在需要使用的所有內容中都可以訪問。與調用JNI_CreateJavaVM()的線程相同的C++線程中的所有內容都將使用由該調用填充的JNIEnv *。想要使用JVM需要調用AttachCurrentThread將線程綁定到JVM並填寫JNIEnv *有效的線程。
  4. 你有沒有仔細檢查你的編譯器/ IDE設置,以確保所有其他線程JDK_HOME/include目錄(其中包含jni.h)位於包含搜索路徑中嗎?JDK_HOME/include/android目錄(或JDK_HOME/include中的操作特定目錄是cal在Android JDK中引導)?

一個非常有用的資源是The JNI book

但要小心,而讀它,因爲一些例子是C和一些在C++,所以一定要了解調用約定的區別。

+0

我更新了我上面的原始代碼。它仍然說,JNI_CreateJavaVM沒有在這個範圍內聲明,即使我已經包含jni.h.此外,因爲我沒有網站()的參數,我是否應該使用NULL作爲env-> CallVoidMethod()的第一個參數? –

+0

Linux上'g ++'的一些實驗表明'void **'的東西是一個紅色的鯡魚(我在C++上生鏽了)。在我測試的時候,我聲明瞭'void foo(void *)'函數,然後像這樣調用它:'int i = 42; foo(&i);',編譯器甚至沒有給出警告,更不用說錯誤了。所以我不認爲'void **'cast的存在與否是相關的。 – QuantumMechanic

+2

'website'方法不會有參數,所以類型簽名應該是'「()V」'不是'「(Ljava/lang/String;)V」' –

0

如果你正在尋找如何調用不以任何參數需要Java方法,格式爲jmethodID mid = env->GetStaticMethodID(myClass, "myMethod", "()V");

()是你告訴它不以任何PARAMS服用。

V表示它返回void。如果方法返回String類型的對象,則應使用Ljava/lang/String;