C++調用Java方法時jvm.dll相關錯誤 【每次記錄完后都被瞬間解決了……】


在編程的學習過程中,愈發感覺到了女性思維在這方面的局限性。

背景介紹:

  為了學習JNI中C++對Java的調用,在閱讀《JNI技術手冊》的同時加以練習。但根據示例代碼編寫過程中總出現各種

奇怪的問題(一度后悔自己裝了win7 64位系統,而電腦之前是預裝win8 32位的...)。由於Java部分的代碼非常簡單,

沒有出現任何錯誤,javac、javah命令也能正常輸出.class文件和頭文件。但C++部分卻報錯了。所學習的示例代碼意圖

通過C++調用Java,生成一個.exe的啟動文件。

  Java代碼如下:    

 1 public class C2Java {
 2     
 3     public C2Java(){
 4         super();
 5     }
 6     
 7     public static int add(int a,int b){
 8         return a+b;
 9     }
10     
11     public boolean judge(boolean bool){
12         return !bool;
13     }    
14 }

  C++代碼如下: 

// c2java.cpp : 定義控制台應用程序的入口點。

#include "stdafx.h"
#include "windows.h"

using namespace std; 

int main(int argc, char* argv[])
{
    JavaVMOption options[1]; 
    JNIEnv *env; 
    JavaVM *jvm; 
    JavaVMInitArgs vm_args; 
    long status; 
    jclass cls; 
    jmethodID mid; 
    jint square; 
    jboolean not; 
    jobject jobj;    
    options[0].optionString = "-Djava.class.path=.";   

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

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

     if(status != JNI_ERR) { 
        cls = env->FindClass("C2Java"); 
        if(cls !=0) { 
            mid = env->GetStaticMethodID(cls, "add", "(II)I"); 
            if(mid !=0) { 
                square = env->CallStaticIntMethod(cls, mid, 5, 5); 
                std::cout << square << std::endl; 
            } 
            mid = env->GetMethodID(cls, "<init>", "()V"); 
            if(mid !=0) { 
                jobj=env->NewObject(cls, mid); 
                std::cout << "init ok"<< std::endl; 
            } 
            mid = env->GetMethodID(cls, "judge", "(Z)Z"); 
            if(mid !=0) { 
                not= env->CallBooleanMethod(jobj, mid, 1); 
                if(!not) { 
                    std::cout << "Boolean ok"<< std::endl; 
                } 
            } 
        } 
        jvm->DestroyJavaVM();  
        return 0; 
    } else
        return -1; 
}

  由於創建jvm過程中可以通過兩種方式加載jvm.dll動態鏈接庫文件,在兩種方式的嘗試中發現了截然不同的錯誤。

  錯誤內容:

  錯誤1:使用如上代碼,通過在path中添加jvm.dll路徑、在工程/屬性/鏈接器/輸出中添加jvm.lib依賴庫,實現dll文件的靜態加載。反復測試了很多次,

始終報錯如下:

  單步調試似乎也不能使用,查閱相關資料,將console改為window報的錯更多…… 之后又仔細搜尋相關教程,根據:http://andy-li-chn.iteye.com/blog/1175075

的說法:“自定義的類JVM無法找到,例子只說讓自己編寫自定義的類,但並沒有說生成的類應該放在什么地方才可以被JVM正確的找到。通常根據需要我們的類是放在特定

的目錄下的,而且放在jvm路徑下也是不安全的,所以在網上的大多數例子都缺少一步,設置自定義類的路徑 "。根據這個思路,決定自定義類路徑並動態加載dll文件。

 錯誤2: 將自己的C++代碼相關部分修改為:

  //定義一個函數指針,下面用來指向JVM中的JNI_CreateJavaVM函數   
    typedef jint (WINAPI *PFunCreateJavaVM)(JavaVM **, void **, void *);   
  const  char  szJvmPath[] = "C:\\Program Files\\Java\\jdk1.7.0_51\\jre\\bin\\server\\jvm.dll";
    HINSTANCE hInstance = ::LoadLibrary(szJvmPath); 
    
    if (hInstance == NULL)   
    {   
        cout<< "LoadLibrary False"<<endl;
        cout<<::GetLastError()<<endl;
        return -2;   
    }   
    //取得里面的JNI_CreateJavaVM函數指針   
    PFunCreateJavaVM funCreateJavaVM = (PFunCreateJavaVM)::GetProcAddress(hInstance, "JNI_CreateJavaVM");   
    status = (*funCreateJavaVM)(&jvm, (void**)&env, &vm_args); 

  運行后返回值為-2,GetLastError的內容為193,意思是動態加載dll文件失敗了。設置斷點查看各變量內容時,發現LoadLibrary的返回值為空。查閱資料后

進行修改仍不能正常運行。目前還未找到方法來成功解決此問題T.T

運行。

  快拯救我吖神奇的博客園... 只希望每次愚蠢的錯誤都能深深印刻在我的腦海里……


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM