2016-09-12 5 views
0

Qtアプリケーションからjava関数を呼び出す必要があります。私はjavaVMを作成するのに成功しましたが、私は自分のJavaクラスを取得するのに問題があります。QtでJava関数を使用

main.cppに

#include <jni.h> 
#include <qDebug> 
#include <string.h> 
#include <windows.h> 

#ifdef _WIN32 
#define PATH_SEPARATOR ';' 
#else 
#define PATH_SEPARATOR ':' 
#endif 

int main() 
{ 
    JavaVMOption options[1]; 
    JNIEnv *env; 
    JavaVM *jvm; 
    JavaVMInitArgs vm_args; 
    long status; 
    jclass cls; 
    jmethodID mid; 
    jint square; 
    typedef jint(JNICALL *pCreateJavaVM)(JavaVM **, void**, void *); 

    HINSTANCE hInstance = LoadLibrary(L"C:\\Program Files (x86)\\Java\\jdk1.8.0_101\\jre\\bin\\client\\jvm.dll"); 
    qDebug()<<"histance"<<hInstance; 
    pCreateJavaVM CreateJavaVM = (pCreateJavaVM)GetProcAddress(hInstance, "JNI_CreateJavaVM"); 

    options[0].optionString = "-Djava.class.path=."; 
    vm_args.version = JNI_VERSION_1_2; 
    vm_args.nOptions = 1; 
    vm_args.options = options; 
    vm_args.ignoreUnrecognized = JNI_TRUE; 
    status = CreateJavaVM(&jvm, (void**)&env, &vm_args); 

    qDebug()<<"status"<<status; 
    if (status != JNI_ERR) 
    { 
     //cls = (env)->FindClass("Test"); 
     cls = (env)->FindClass("java/Test"); 
     if(cls !=0) 
     { mid = (env)->GetStaticMethodID(cls, "intMethod", "(I)I"); 
      if(mid !=0) 
      { 
       square = (env)->CallStaticIntMethod(cls, mid, 5); 
       qDebug()<<"square"<<"5²"<<square; 
      }else qDebug()<<"function not found"; 

     } else qDebug()<<"class not found"; 

     (jvm)->DestroyJavaVM(); 
     return 0; 
    } 
    else 
     qDebug()<<"jni error"<<status; 
     return -1; 
} 

Test.java

public class Test 
    { 
    public static int intMethod(int n) { 
     return n*n; 
    } 
} 

.PRO

TEMPLATE = app 

CONFIG += c++11 

SOURCES += main.cpp 

# Default rules for deployment. 
include(deployment.pri) 

INCLUDEPATH += "C:/Program Files (x86)/Java/jdk1.8.0_101/include" 
DEPENDPATH += "C:/Program Files (x86)/Java/jdk1.8.0_101/include" 

INCLUDEPATH += "C:/Program Files (x86)/Java/jdk1.8.0_101/include/win32" 
DEPENDPATH += "C:/Program Files (x86)/Java/jdk1.8.0_101/include/win32" 

LIBS += -L"C:/Program Files (x86)/Java/jdk1.8.0_101/lib/" -ljvm 

HEADERS += 

DISTFILES += \ 
    java/Test.java 

フォルダ

MyProject/ 
    |__MyProject.pro 
    |__MyProject.pro.user 
    |__deployment.pri 
    |__main.cpp 
    |__java/ 
     |__Test.java 

私は、ファイルが間違った場所にありますが、私はそれをコピーする必要がどこ私にはわからないと思います


編集:私は.classファイル(javacのと)、私のファイルを編集するために私のファイルの.javaをコンパイルしている main.cppに:

#include <jni.h> 
#include <qDebug> 
#include <string.h> 
#include <windows.h> 

#ifdef _WIN32 
#define PATH_SEPARATOR ';' 
#else 
#define PATH_SEPARATOR ':' 
#endif 

int main() 
{ 
    JavaVMOption options[1]; 
    JNIEnv *env; 
    JavaVM *jvm; 
    JavaVMInitArgs vm_args; 
    long status; 
    jclass cls; 
    jmethodID mid; 
    jint square; 
    typedef jint(JNICALL *pCreateJavaVM)(JavaVM **, void**, void *); 

    HINSTANCE hInstance = LoadLibrary(L"C:\\Program Files (x86)\\Java\\jdk1.8.0_101\\jre\\bin\\client\\jvm.dll"); 
    qDebug()<<"histance"<<hInstance; 
    pCreateJavaVM CreateJavaVM = (pCreateJavaVM)GetProcAddress(hInstance, "JNI_CreateJavaVM"); 

    options[0].optionString = "-Djava.class.path=classes:."; 
    vm_args.version = JNI_VERSION_1_2; 
    vm_args.nOptions = 1; 
    vm_args.options = options; 
    vm_args.ignoreUnrecognized = JNI_TRUE; 
    status = CreateJavaVM(&jvm, (void**)&env, &vm_args); 

    qDebug()<<"status"<<status; 
    if (status != JNI_ERR) 
    { 
     cls = (env)->FindClass("Test"); 
     if(cls !=0) 
     { mid = (env)->GetStaticMethodID(cls, "intMethod", "(I)I"); 
      if(mid !=0) 
      { 
       square = (env)->CallStaticIntMethod(cls, mid, 5); 
       qDebug()<<"square"<<"5²"<<square; 
      }else qDebug()<<"function not found"; 

     } else qDebug()<<"class not found"; 

     (jvm)->DestroyJavaVM(); 
     return 0; 
    } 
    else 
     qDebug()<<"jni error"<<status; 
     return -1; 
} 

フォルダ私のクラスが見つからない

MyProject/ 
    |__MyProject.pro 
    |__MyProject.pro.user 
    |__deployment.pri 
    |__main.cpp 
    |__classes/ 
     |__Test.class 

答えて

1

3つのもの:

  1. .javaファイルはjavacで.classファイルにコンパイルする必要があります。このTest.classファイルを "classes"ディレクトリに置きます。

  2. の.classファイルが

    -Djava.class.pathも=が宣言したパスに到達可能である必要があります。

    と答えてください。

    -Djava.class.path = classes :.

  3. FindClassは、パスではなくクラス名をとるだけです。だから、それは "テスト"でなければなりません。

+0

ありがとう、私は同じ結果を持っています。たぶん私は警告があるため "文字列定数から 'char *'への非難された変換;私は私の投稿を編集している – helene

+0

警告は問題ありません。コンパイルされたバイナリが "out"ディレクトリなどにドロップされるのでしょうか?そのディレクトリにTest.classファイルを入れてみてください。 –

+0

はい、そうです。 – helene

関連する問題