2017-06-30 202 views
0

我嘗試通過C++/Qt程序實現JNI以訪問JAVA類。未找到JNI類

我跟着這個例子的generell部分。 https://www.codeproject.com/Articles/993067/Calling-Java-from-Cplusplus-with-JNI 只需稍微改變一下以適應Qt程序。

現在我試着解決這個「class not found」錯誤。 我讀了很多這個問題的其他問題,並在選項[0] .optionString中使用不同的路徑符號。 test.class文件與.exe一樣是int目錄,我檢查了這是程序的CWD。

我忽略了一些顯而易見的事情,還是會有更多的問題?

非常感謝!

#include "MyXPS.h" 

JavaVM *jvm;      // Pointer to the JVM (Java Virtual Machine) 
JNIEnv *env;      // Pointer to native interface 


MyXPS::MyXPS(void) 
{ 
} 

MyXPS::~MyXPS(void) 
{ 
    jvm->DestroyJavaVM(); 
} 

QString MyXPS::InitializeJNI() 
{ 
     //================== prepare loading of Java VM ============================ 
    JavaVMInitArgs vm_args;      // Initialization arguments 
    JavaVMOption* options = new JavaVMOption[1]; // JVM invocation options 
    options[0].optionString = "-Djava.class.path=."; // where to find java .class "-Djava.class.path=c:\\Users\\admin\\Desktop\\Release" "-Djava.class.path=C:/Users/admin/Desktop/Release/" (char *) 
    vm_args.version = JNI_VERSION_1_6;    // minimum Java version 
    vm_args.nOptions = 1;       // number of options 
    vm_args.options = options; 
    vm_args.ignoreUnrecognized = false;  // invalid options make the JVM init fail 
     //=============== load and initialize Java VM and JNI interface ============= 
    jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !! 
    delete options; // we then no longer need the initialisation options. 

    if (rc != JNI_OK) { 
     // TO DO: error processing... 
     if(rc == JNI_EVERSION) 
      return "FATAL ERROR: JVM is oudated and doesn't meet requirements"; 
     else if(rc == JNI_ENOMEM) 
      return "FATAL ERROR: not enough memory for JVM"; 
     else if(rc == JNI_EINVAL) 
      return "FATAL ERROR: invalid ragument for launching JVM"; 
     else if(rc == JNI_EEXIST) 
      return "FATAL ERROR: the process can only launch one JVM an not more"; 
     else 
      return "FATAL ERROR: could not create the JVM instance (error code " + QString::number(rc) + ")"; 
    } 
    return "Initialization successfull"; 
} 

QString MyXPS::getVersion() 
{ 
     //=============== Display JVM version ======================================= 
    jint ver = env->GetVersion(); 
    //return((ver>>16)&0x0f)+"."+(ver&0x0f); 
    return QString::number(ver); 
} 

QString MyXPS::test(double height, double weight) 
{ 
    jclass cls2 = env->FindClass("test"); // try to find the class 
    if(cls2 == 0) 
    { 
     return "class not found"; 
    } 

    else 
    {         // if class found, continue 
     //cout << "Class MyTest found" << endl; 
     jmethodID mid = env->GetStaticMethodID(cls2, "demo", "(DD)Ljava/lang/String;"); // find method 
     if(mid == NULL) 
     { 
      //cerr << "ERROR: method void mymain() not found !" << endl; 
      return "ERROR: method void mymain() not found !"; 
     } 
     else 
     { 
      jobject result = env->CallStaticObjectMethod(cls2, mid, (jdouble)height, (jdouble)weight);      // call method 
      const char* str = env->GetStringUTFChars((jstring) result, NULL); 
      QString Qresult = QString::fromLocal8Bit(str); 
      return Qresult; 
     } 
    } 
} 

好的,我實現了一些代碼來獲取異常,它是NoClassDefFoundError。所以它不是關於.class文件的路徑。現在我將在Java中檢查如此的編譯和rumtime路徑。

+0

不是100%肯定的確切位置,但爲什麼不乾脆用QAndroidJniObject http://doc.qt.io/qt-5/ qandroidjniobject.html?這裏有一個很好的教程:https://www.kdab.com/qt-android-episode-7/ – FourtyTwo

+0

感謝您的建議,但是當前的Qt版本是4.7,並且不包括與Android相關的函數。更新Qt版本將在未來某個時間完成。但是這需要在之前完成。 – Henning

回答

0

我知道這是不完全適合你的情況下的解決方案,但你可以看看這裏:

http://jnicookbook.owsiak.org/recipe-no-027/

此示例演示如何從C代碼中調用類。它看起來像你的情況問題是相關的類路徑。確保你的C代碼知道你的代碼的.class文件測試