2015-04-22 175 views
1

我想在Visual Studio C++環境中從Java類運行幾個方法。我得到了一個與CreateJavaVM相關的錯誤。使用jni.h編譯C++中的java方法時出現錯誤

請您幫我找到解決方案嗎?

我做了以下步驟。

第1步: JDK 1.6以下路徑下安裝:C:\ Program Files文件\的Java 以下2個子目錄在那裏:jdk1.6.0_45,JRE6

第2步:寫一個簡單的java程序。

public class Sample2 
{ 
    public static int intMethod(int n) 
    { 
    return n*n; 
    } 
    public static boolean booleanMethod(boolean bool) 
    { 
    return !bool; 
    } 
} 

步驟3:編譯Java代碼:

javac Sample2.java 

步驟4:創建一個Visual Studio C++程序。 Visual C++ CLR控制檯應用程序。

第5步:添加其他依賴項。 (jvm.lib和jvm.dll) a)選擇項目 - >屬性 - >鏈接器 - >輸入 - >其他依賴項:jvm.lib b)選擇項目 - >屬性 - >鏈接器 - >輸入 - >延遲加載的DLL:jvm.dll的

第6步:添加包括目錄 a)選擇項目 - >屬性 - >配置屬性 - > C/C++ - >常規 - >附加包含目錄:C:\ Program Files文件\的Java \ jdk1.6.0_45 \ lib中; C:\ Program Files \ Java \ jdk1.6.0_45 \ include \ win32; C:\ Program Files \ Java \ jdk1.6.0_45 \ include

第7步:編寫C++代碼來運行java方法。

#include "stdafx.h" 
    #include "jni.h" 
    #include <jni_md.h> 
    using namespace System; 

    int main(array<System::String ^> ^args) 
    { 

    JavaVM *jvm; /* denotes a Java VM */ 
    JNIEnv *env; /* pointer to native method interface */ 
    jint square; 
    jboolean not; 

    JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */ 

    JavaVMOption *options = new JavaVMOption[1]; 

    options[0].optionString = "-Djava.class.path=C:\\JavaCode"; 

    vm_args.version = JNI_VERSION_1_6; 
    vm_args.options = options; 
    vm_args.nOptions = 1; 
    vm_args.ignoreUnrecognized = false; 

    int res = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args); 

    jclass cls = env->FindClass("Sample2"); 

    jmethodID mid = env->GetStaticMethodID(cls, "staticInt", "(I)I"); 

    env->CallStaticVoidMethod(cls, mid,10); 

    if(cls !=0) 
    { 
    mid = env->GetStaticMethodID(cls,"intMethod","(I)I");  

    if(mid !=0) 
    { 
    square = env->CallStaticIntMethod(cls, mid, 5);  
    printf("Result of intMethod: %d\n", square); 
    } 

    mid = env->GetStaticMethodID(cls, "booleanMethod", "(Z)Z"); 

    if(mid !=0) 
    { 
    not = env->CallStaticBooleanMethod(cls, mid, 1); 
    printf("Result of booleanMethod: %d\n", not); 
    } 
} 

jvm->DestroyJavaVM(); 

Console::Read(); 
return 0; 
} 

步驟8:當我建我得到了以下錯誤的項目:

1>------ Build started: Project: 1, Configuration: Debug Win32 ------ 

1>LINK : warning LNK4199: /DELAYLOAD:jvm.dll ignored; no imports found from jvm.dll 

1>1.obj : warning LNK4248: unresolved typeref token (0100000F) for '_jmethodID'; image may not run 

1>1.obj : error LNK2028: unresolved token (0A000016) "extern "C" long __stdcall JNI_CreateJavaVM(struct JavaVM_ * *,void * *,void *)" ([email protected]@[email protected]@[email protected]) referenced in function "int __clrcall main(cli::array<class System::String^>^)" ([email protected]@[email protected]@@@Z) 

1>1.obj : error LNK2019: unresolved external symbol "extern "C" long __stdcall JNI_CreateJavaVM(struct JavaVM_ * *,void * *,void *)" ([email protected]@[email protected]@[email protected]) referenced in function "int __clrcall main(cli::array<class System::String^>^)" ([email protected]@[email protected]@@@Z) 

1>C:\Users\tveluppillai\Desktop\Test1\1\Debug\1.exe : fatal error LNK1120: 2 unresolved externals 

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

有沒有人幫我解決這個錯誤嗎?

回答

0

所以,我解決了這個錯誤。以下是工作的C++代碼。

// 1.cpp : main project file. 

    #include "stdafx.h" 
    #include "jni.h" 
    #include <windows.h> 
    using namespace System; 


    int CallJava() 
    { 

    JavaVM *jvm; /* denotes a Java VM */ 

    JNIEnv *env; /* pointer to native method interface */ 

    jint square; 

    jboolean not; 

    JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */ 

    JavaVMOption *options = new JavaVMOption[1]; 

    options[0].optionString = "-Djava.class.path=C:\\JavaCode"; 

    vm_args.version = JNI_VERSION_1_6; 
    vm_args.options = options; 
    vm_args.nOptions = 1; 
    vm_args.ignoreUnrecognized = false; 

    HINSTANCE hinstLib; 

    hinstLib = LoadLibrary(TEXT("C:\\Program Files\\Java\\jdk1.6.0_45\\jre\\bin\\server\\jvm.dll")); 

    if(hinstLib==0) 
    { 
    printf("Error"); 
    } 

    if(hinstLib!= NULL) 
    { 
    typedef jint (JNICALL *PtrCreateJavaVM)(JavaVM **, void **, void *); 

    PtrCreateJavaVM ptrCreateJavaVM = (PtrCreateJavaVM)GetProcAddress(hinstLib,"JNI_CreateJavaVM"); 

    int res = ptrCreateJavaVM(&jvm, (void**)&env, &vm_args); 

    jclass cls = env->FindClass("Sample2"); 

    jmethodID mid; 

    if(cls !=0) 
    { 
    mid = env->GetStaticMethodID(cls,"intMethod","(I)I"); 
    if(mid !=0) 
    { 
     square = env->CallStaticIntMethod(cls, mid, 5);  
     printf("Result of intMethod: %d\n", square); 
    } 

    mid = env->GetStaticMethodID(cls, "booleanMethod", "(Z)Z"); 
    if(mid !=0) 
    { 
    not = env->CallStaticBooleanMethod(cls, mid, 1); 
    printf("Result of booleanMethod: %d\n", not); 
    } 
    } 
    jvm->DestroyJavaVM(); 
} 
else 
{ 
    printf("Library is NULL"); 
} 
    Console::Read(); 
    return 0; 
} 

int main(array<System::String ^> ^args) 
{ 
CallJava(); 
Console::Read(); 
return 0; 
} 
0

JNI_CreateJavaVM定義在jni.h,所以我的猜測是你的鏈接器沒有找到jni.h。我實際上把該文件和jni_md.h與我的源代碼放在我的項目目錄中。

請注意,jni.h包括jni_md.h,所以在您的源代碼中有#include <jni_md.h>是多餘的。

+0

我在C++解決方案文件夾中添加了頭文件。我仍然收到同樣的錯誤。 –

+0

好吧,錯誤是一個鏈接器錯誤,所以它沒有找到它。我們不介意讀者。如果沒有親身體驗項目中的所有設置,我都不知道你搞錯了什麼。如果您將jvm.lib添加爲依賴項,那麼鏈接器應該找到它。如果您可以嘗試發佈實際的編譯和鏈接文本命令。 –

+0

它肯定是一個鏈接錯誤。由於我使用Visual Studio IDE,所以我不必編寫任何命令來編譯和鏈接。這就是我所做的。第1步:右鍵單擊項目並選擇屬性,然後轉到鏈接器 - >輸入並在附加依賴項中鍵入jvm.lib,並在Dealyed Loaded Dll中鍵入jvm.dll第2步:轉到鏈接器下的常規,並指定路徑附加庫目錄中的jvm.lib和jvm.dll。 C:\ Program Files \ Java \ jdk1.6.0_45 \ lib; C:\ Program Files \ Java \ jre6 \ bin \ server;%(AdditionalLibraryDirectories) –