2017-06-30 23 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文件测试