JNI學習—–C語言調用Java

來源:互聯網
上載者:User
 

原文地址: http://blog.csdn.net/sunchaoenter/article/details/6598719

最近項目中需要使用JNI,所以研究了一下,其中遇到過不少問題,總結一下,讓遇到同樣問題的人可以得到解決。

在C/C++中調用Java的方法一般分為五個步驟:初始化虛擬機器、擷取類、擷取類的方法、建立類對象、調用方法和退出虛擬機器。

下面寫一個小程式測試一下:

Java代碼:

view plaincopy to clipboardprint?
  1. package jni.test;  
  2.   
  3. public class Demo {  
  4.   
  5.     public static int COUNT = 8;  
  6.   
  7.     public String msg;  
  8.     private int[] counts;  
  9.   
  10.     public Demo() {  
  11.         this("預設建構函式");  
  12.     }  
  13.   
  14.     public Demo(String msg) {  
  15.         System.out.println("<init>:" + msg);  
  16.         this.msg = msg;  
  17.         this.counts = null;  
  18.     }  
  19.   
  20.     public String getMessage() {  
  21.         return msg;  
  22.     }  
  23.   
  24.     public int[] getCounts() {  
  25.         return counts;  
  26.     }  
  27.   
  28.     public void setCounts(int[] counts) {  
  29.         this.counts = counts;  
  30.     }  
  31.   
  32.     public void throwExcp() throws IllegalAccessException {  
  33.         throw new IllegalAccessException("exception occur.");  
  34.     }  
  35. }  

package jni.test;public class Demo {public static int COUNT = 8;public String msg;private int[] counts;public Demo() {this("預設建構函式");}public Demo(String msg) {System.out.println("<init>:" + msg);this.msg = msg;this.counts = null;}public String getMessage() {return msg;}public int[] getCounts() {return counts;}public void setCounts(int[] counts) {this.counts = counts;}public void throwExcp() throws IllegalAccessException {throw new IllegalAccessException("exception occur.");}}

上面的代碼很好理解,我相信你能看的懂,我就不說了。

下面是C語言代碼,裡面有注釋,這裡先不詳細說明,主要先跑起來再說:

view plaincopy to clipboardprint?
  1. #include <stdio.h>   
  2. #include <jni.h>   
  3. #include <stdlib.h>   
  4. #include <iostream.h>   
  5. int main() {  
  6.     // 定義用到的變數   
  7.     int res;  
  8.     JavaVM *jvm;  
  9.     JNIEnv *env;  
  10.     JavaVMInitArgs vm_args;  
  11.     JavaVMOption options[3];  
  12.     vm_args.version;  
  13.       
  14.     // 設定初始化參數   
  15.     options[0].optionString = "-Djava.compiler=NONE";  
  16.     // classpath有多個時,用";"分隔,UNIX下以":"分割。   
  17.     options[1].optionString = "-Djava.class.path=.";  
  18.     // 用於跟蹤運行時的資訊   
  19.     options[2].optionString = "-verbose:jni";  
  20.     // 版本號碼設定不能漏   
  21.     vm_args.version = JNI_VERSION_1_6;  
  22.     vm_args.nOptions = 3;  
  23.     vm_args.options = options;  
  24.     vm_args.ignoreUnrecognized = JNI_TRUE;  
  25.     // 1.初始化虛擬機器   
  26.     res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);  
  27.     if (res < 0)  
  28.     {  
  29.         fprintf(stderr, "Can't create Java VM\n");  
  30.         exit(1);  
  31.     }  
  32.     // 2.擷取類   
  33.     jclass cls = env->FindClass("jni/test/Demo");  
  34.     // 3.擷取類的方法   
  35.     jmethodID mid= env->GetMethodID(cls,"getMessage","()Ljava/lang/String;");  
  36.     // 擷取Java的構造方法   
  37.     jmethodID con=env->GetMethodID(cls,"<init>","(Ljava/lang/String;)V");  
  38.     jstring strinit = env->NewStringUTF("Still is coding!");  
  39.     jvalue arg[1];  
  40.     arg[0].l = strinit;  
  41.     //env->AllocObject(cls);   
  42.     // 4.建立類的對象   
  43.     jobject obj = env->NewObjectA(cls,con,arg);  
  44.     // 調用對象的方法   
  45.     jstring msg = (jstring)env-> CallObjectMethod(obj, mid);  
  46.       
  47.     cout<<msg<<endl;  
  48.     char *str=(char *)env->GetStringUTFChars(msg,JNI_FALSE);  
  49.     printf("%s===",str);  
  50.     // 5.退出虛擬機器   
  51.     jvm->DestroyJavaVM();  
  52.     fprintf(stdout, "Java VM destory.\n");  
  53.     return 0;  
  54. }  

把以上C語言代碼用VC6.0開啟,然後編譯,下面問題就來了,我們一個一個解決。

編譯的時候首先會出現如下問題:

錯誤很明顯,我們上麵包含了jni.h,但是沒找到。這是需要設定一下VC。

Tools->Options->Directories,添加JDK安裝目錄下的兩個目錄,

同時在Library files中添加JDK下面的LIB目錄,如:

點擊OK完成,重新編譯。

好,新問題又來了,看下面描述:

也很明顯,說明沒有找到jvm.lib。繼續設定VC,Project->Settings->Link->Object/library modules中把上述路徑替換為本機實際安裝JDK中的jvm.lib目錄,添加完後如:

點擊OK後重新編譯,呵呵,又來問題了,我很高興啊。

這個問題在網上查了一下,原來是我JDK安裝在Program Files下的問題,因為Program Files路徑中有一個空格,真鬱悶,沒辦法,只好重裝JDK,注意安裝目錄中不能再有空格了。安裝完了,按照上面出現的問題再重新設定一下VC,然後編譯,沒問題,運行,哇靠,又是一個問題:

這個問題可是花了我大半天時間才搞定的,但其實做法很簡單。

看錯描述,是沒找到jvm.dll,網上很多人說直接找到這個檔案把它拷貝到目前的目錄。但是這種方法不可取,因為jvm.dll這個東東還會依賴其他的檔案的,而且它找其它所依賴的檔案是通過相對路徑找的,你直接就搞這麼一個檔案出來,其它的也找不到啊。所以這裡有一個很好的解決方案,就是把D:\Java\jdk1.6.0_23\jre\bin\client這個JDK下的路徑加入Path環境變數,加完之後記得重新用VC開啟CPP檔案,這個很重要,否則,這個問題還是沒有解決。

點擊編譯,運行,如果出現如下畫面,OK,恭喜你,C語言調用Java成功了,下面要做的就是去看代碼,並且瞭解啟動並執行機理了,這個我就不多說了。

原始碼下載:http://download.csdn.net/source/3434985

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.