2011-09-24 66 views
16

我想從C調用Java虛擬機++下面的例子中找到here調用Java從C++

基本上我有一個小型的Java程序:

public class TestJNIInvoke 
{ 
    public static void main(String[] args) 
    { 
    System.out.println(args[0]); 
    } 
} 

然後,我有一個C++程序我想創建一個JVM,並調用TestJNIInvoke類:

#include <jni.h> 
#include <cstdlib> 
#define PATH_SEPARATOR ';' /* define it to be ':' on Solaris */ 
#define USER_CLASSPATH "." /* where Prog.class is */ 

using namespace std; 

int main() { 
    JNIEnv *env; 
    JavaVM *jvm; 
    jint res; 
    jclass cls; 
    jmethodID mid; 
    jstring jstr; 
    jclass stringClass; 
    jobjectArray args; 

#ifdef JNI_VERSION_1_2 
    JavaVMInitArgs vm_args; 
    JavaVMOption options[1]; 
    options[0].optionString = 
     "-Djava.class.path=" USER_CLASSPATH; 
    vm_args.version = 0x00010002; 
    vm_args.options = options; 
    vm_args.nOptions = 1; 
    vm_args.ignoreUnrecognized = JNI_TRUE; 
    /* Create the Java VM */ 
    res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); 
#else 
    JDK1_1InitArgs vm_args; 
    char classpath[1024]; 
    vm_args.version = 0x00010001; 
    JNI_GetDefaultJavaVMInitArgs(&vm_args); 
    /* Append USER_CLASSPATH to the default system class path */ 
    sprintf(classpath, "%s%c%s", 
      vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH); 
    vm_args.classpath = classpath; 
    /* Create the Java VM */ 
    res = JNI_CreateJavaVM(&jvm, &env, &vm_args); 
#endif /* JNI_VERSION_1_2 */ 

    if (res < 0) { 
     fprintf(stderr, "Can't create Java VM\n"); 
     exit(1); 
    } 
    cls = (*env)->FindClass(env, "TestJNIInvoke"); 
    if (cls == NULL) { 
     goto destroy; 
    } 

    mid = (*env)->GetStaticMethodID(env, cls, "main", 
            "([Ljava/lang/String;)V"); 
    if (mid == NULL) { 
     goto destroy; 
    } 
    jstr = (*env)->NewStringUTF(env, " from CPP!"); 
    if (jstr == NULL) { 
     goto destroy; 
    } 
    stringClass = (*env)->FindClass(env, "java/lang/String"); 
    args = (*env)->NewObjectArray(env, 1, stringClass, jstr); 
    if (args == NULL) { 
     goto destroy; 
    } 
    (*env)->CallStaticVoidMethod(env, cls, mid, args); 

destroy: 
    if ((*env)->ExceptionOccurred(env)) { 
     (*env)->ExceptionDescribe(env); 
    } 
    (*jvm)->DestroyJavaVM(jvm); 
} 

但是當我試圖編譯C++程序中,我得到這個錯誤:

c:\java\JNI> g++ -I"c:\Program Files\Java\jdk1.7.0\include"-I"c:\ProgramFiles\Java\jdk1.7.0\include\win32" -c TestJNIInvoke.cpp 


TestJNIInvoke.cpp: In function 'int main()': 
TestJNIInvoke.cpp:20:31: warning: deprecated conversion from string constant to 
'char*' 
TestJNIInvoke.cpp:44:18: error: base operand of '->' has non-pointer type 'JNIEn 
v' 
TestJNIInvoke.cpp:49:18: error: base operand of '->' has non-pointer type 'JNIEn 
v' 
TestJNIInvoke.cpp:54:19: error: base operand of '->' has non-pointer type 'JNIEn 
v' 
TestJNIInvoke.cpp:58:26: error: base operand of '->' has non-pointer type 'JNIEn 
v' 
TestJNIInvoke.cpp:59:19: error: base operand of '->' has non-pointer type 'JNIEn 
v' 
TestJNIInvoke.cpp:63:12: error: base operand of '->' has non-pointer type 'JNIEn 
v' 
TestJNIInvoke.cpp:66:16: error: base operand of '->' has non-pointer type 'JNIEn 
v' 
TestJNIInvoke.cpp:67:16: error: base operand of '->' has non-pointer type 'JNIEn 
v' 
TestJNIInvoke.cpp:69:12: error: base operand of '->' has non-pointer type 'JavaVM' 

任何想法?

感謝

+0

您應該包含關於什麼不適用於您的代碼的評論。你得到一個錯誤還是隻是不工作? –

+0

我不知道從C++調用Java的任何內容,但是您將'env'聲明爲一個指針('JNIEnv * env'),所以當你執行'(* env) - >任何事情時'它會抱怨,因爲' * env'不是一個指針。嘗試'env->任何東西'。 – dantswain

+0

或者:使用點('.')而不是箭頭(' - >')。 JVM對象也出現同樣的問題:'(* jvm)'。此外,某處字符串文字被隱式轉換爲'char *',因此您可能希望使用_explicit_來代替。 (這將擺脫警告)。 – user268396

回答

38

儘管包含相同的頭文件,但Java本機接口爲C和C++使用了兩個不同的接口。

在C++中,它是:

jclass cls = env->FindClass("java/lang/String"); 

,而不是(爲C):

jclass cls = (*env)->FindClass(env, "java/lang/String"); 

所以C函數調用,需要兩個env地成爲在C方便的成員函數調用++。

這在Java Native Interface 6.0 SpecificationNative Method Arguments部分提及。

+0

非常感謝,我不知道有不同的接口。這會讓我的生活變得更輕鬆。 :) –

1

我的猜測是,你試圖編譯針對給定你使用命令行的win32頭。您是否嘗試過-I"c:\ProgramFiles\Java\jdk1.7.0\include\solaris(假設您的平臺基於源代碼中較高的評論)。

+0

這不是頭文件的問題,這是一個不正確的語法問題。用於通過指針( - >)訪問對象成員/方法的語法用於通過指針解引用(* env)提供值的位置。 – user268396

+0

啊,對不起,同意了。我沒有發現滾動條,只查看了代碼段頂部的代碼,其中沒有包含任何問題代碼。 –