程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 【Java的JNI快速學習教程】,javajni快速學習

【Java的JNI快速學習教程】,javajni快速學習

編輯:JAVA綜合教程

【Java的JNI快速學習教程】,javajni快速學習


 1. JNI簡介


  JNI是Java Native Interface的英文縮寫,意為Java本地接口。

  問題來源:由於Java編寫底層的應用較難實現,在一些實時性要求非常高的部分Java較難勝任(實時性要求高的地方目前還未涉及,實時性這類話題有待考究)。

  解決辦法:Java使用JNI可以調用現有的本地庫(C/C++開發任何和系統相關的程序和類庫),極大地靈活Java的開發。

2. JNI快速學習教程


2.1 問題:

  使用JNI寫一段代碼,實現string_Java_Test_helloworld(JNIEnv *env, jclass cls , jstring j_str)函數,實現在字符串j_str("world")前面加上hello,並返回。

2.2 解決問題過程:

  I. 編寫Test.java類:

 1 public class Test{
 2     // native interface
 3     public native String helloworld(String text);
 4     
 5     public static void main(String[] args){
 6         // Load dynamic library
 7         System.loadLibrary("Test2");
 8         Test ts = new Test();
 9         String text = ts.helloworld("world");
10         System.out.println(text);
11     }
12 }

  備注:

    1、加載動態類庫:System.loadLibrary("Test2");【Windows下加載的就是Test2.dll,Linux下加載的是Test2.so】

  II. 編譯Test.java文件

    進入cmd輸入命令 > javac Test.java

  III. 生成Test.h文件

    進入cmd輸入命令 > javah Test

  Test.h文件內容如下:

 1 /* DO NOT EDIT THIS FILE - it is machine generated */
 2 #include <jni.h>
 3 /* Header for class Test */
 4 
 5 #ifndef _Included_Test
 6 #define _Included_Test
 7 #ifdef __cplusplus
 8 extern "C" {
 9 #endif
10 /*
11  * Class:     Test
12  * Method:    helloworld
13  * Signature: (Ljava/lang/String;)Ljava/lang/String;
14  */
15 JNIEXPORT jstring JNICALL Java_Test_helloworld
16   (JNIEnv *, jobject, jstring);
17 
18 #ifdef __cplusplus
19 }
20 #endif
21 #endif

  備注:

    1、函數聲明,固定格式:JNIEXPORT;返回類型:jstring;JNI調用:JNICALL;Java_完整類名_方法名:Java_Test_helloworld;

    2、函數參數:調用jni.h封裝好的函數指針:JNIEnv;Java類本身:jobject,Java文件傳入參數:jstring。

  IV. 編寫C語言文件Test2.c實現Test類調用動態鏈接庫的功能:

 1 #include "Test.h"
 2 #include <string.h>
 3 
 4 JNIEXPORT jstring JNICALL Java_Test_helloworld
 5   (JNIEnv *env, jobject obj, jstring string){
 6     const char* str = (*env)->GetStringUTFChars(env,string,0);
 7     char cap[128];
 8     cap[0] = 'h';
 9     cap[1] = 'e';
10     cap[2] = 'l';
11     cap[3] = 'l';
12     cap[4] = 'o';
13      
14     strcat(cap,str);
15       
16     (*env)->ReleaseStringUTFChars(env,string,0);
17     return (*env)->NewStringUTF(env,cap);
18   }

  備注:

    1、由於Java本身使用了雙字節字符,C語言本身都是單字節字符,所以需要使用(*env)->GetStringUTFChars()轉換Java和C之間的字符串;

    2、GetStringUTFChars()和NewStringUTF(),第一個是從UTF8轉換為C的編碼格式,第二個是根據C的字符串返回一個UTF8字符串;

    3、ReleaseStringUTFChars()是用來釋放對象的,在Java中有虛擬機進行垃圾回收,但是在C語言中這些對象必須手動回收,否則可能造成內存洩漏。

  V. 編譯和運行

  編譯:

    進入cmd輸入命令 > gcc -I "D:\Program Files\Java\jdk1.8.0_45\include" -I "D:\Program Files\Java\jdk1.8.0_45\include\win32" --share Test2.c -o Test2.dll

  運行:

    進入cmd輸入命令 > java Test

  運行結果如下:

    helloworld

3. 總結:


  第一步:編寫帶有native方法的Java類(Test.java),使用javac工具編譯Java類(生成Test.class);

  第二步:使用javah生成與native方法對應的頭文件(Test.h);

  第三步:使用C/C++實現相應的頭文件(Test2.c),並編譯為動態鏈接庫(Test2.so)。

  本文運行環境:Windows 64位操作系統,JDK 1.8版本,mingw64(GCC)。

4. 參考:


  http://www.cnblogs.com/icejoywoo/archive/2012/02/22/2363709.html

 【轉載本文章請備注原地址出處:http://www.cnblogs.com/eesijian/p/5843879.html 】

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved