跨平臺的JAVA調不跨平臺的C--(JNI在Win32&&Linux下的使用)

             由于java程序需要調用C或C++的代碼,不得不使用JNI。C的代碼在Win32和Linux下都有相同功能的不同實現,就像JDK分幾種平臺版本(win32,linux,solaris等)。
             首先,看一看首先,看一看win32下調用dll文件。
              1, 新建HelloWorld.java
           1public class HelloWorld
           2
          {
           3  static

           4  {
           5    try

           6    {
           7      //此處即為本地方法所在鏈接庫名

           8      System.loadLibrary("HelloWorld");
           9    }
          catch(UnsatisfiedLinkError e){
          10      System.err.println( "不能加載dll文件:\n " +
          e.toString() );
          11    }

          12  }
          //end static
          13 public native void SayHello(String strName);
          14

          15}

          16
            2,  編譯java文件生成HelloWorld.class文件
            3,在命令行下,javah -jni HelloWorld 生成 HelloWorld.h 文件
            
           1/* DO NOT EDIT THIS FILE - it is machine generated */
           2#include <jni.h>
           3/* Header for class HelloWorld */
           4
           5
          #ifndef _Included_HelloWorld
           6
          #define _Included_HelloWorld
           7
          #ifdef __cplusplus
           8
          extern "C" {
           9
          #endif
          10
          /*
          11 * Class:     HelloWorld
          12
           * Method:    SayHello
          13
           * Signature: (Ljava/lang/String;)
          14 */

          15JNIEXPORT void JNICALL Java_HelloWorld_SayHello
          16  (JNIEnv *
          , jobject, jstring);
          17

          18
          #ifdef __cplusplus
          19
          }
          20
          #endif
          21
          #endif
          22
            4,   編寫HelloWorld.cpp
           1#include <windows.h>
           2#include "HelloWorld.h"
           3#include <stdio.h>
           4//與Hello.h中函數聲明相同
           5JNIEXPORT void JNICALL Java_HelloWorld_SayHello (JNIEnv * env, jobject arg, jstring instring)
           6
          {
           7//從instring字符串取得指向字符串UTF編碼的指針

           8  const jbyte *str = 
           9   (const jbyte *)env->
          GetStringUTFChars( instring, JNI_FALSE );
          10printf("HelloWorld,%s\n"
          ,str);
          11  //通知虛擬機本地代碼不再需要通過str訪問Java字符串。

          12env->ReleaseStringUTFChars( instring, (const char *)str );
          13return
          ;
          14}
           
          15int
           WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
          16
          {
          17    return
           TRUE ;
          18}
          5,  在vc6下新建dll工程HelloWorld,加載HelloWorld.h和HelloWorld.cpp,編譯生成HelloWorld.dll文件,最關鍵的是引用JAVAHOME\include\和JAVAHOME\include\win32的.h文件。
          6,設置classpath為dll文件所在路徑,新建一個測試類TestHelloWorldDLL.java
          1public class HelloWorld {
          2public static void main(String args[]){
          3        HelloWorld hw = new HelloWorld();
          4        hw.SayHello("Christmas");    
          5    }

          6}

          7,  輸出結果: HelloWorld Christmas
          =======================================================================================================

           接下來,在linux下調用so試一試。
           因為linux下不能用vc所以gcc,如下命令:
          #gcc -I/usr/java/include -shared -o libHelloWorld.so HelloWorld.cpp 
              運行測試程序,發現不能導入.so文件,提示no HelloWorld  in java.library.path,所以需要設置java.library.path。
           
          java -Djava.library.path=`pwd` -cp .  MyNative
          注意我把.so文件拷到了當前路徑,其他路徑設置即可!
          再執行,ok了,輸出正確結果!
           
          最后,總結一下:
            jni的使用很簡單,麻煩的是抽象出所調用dll或so文件的接口封裝成native方法。另外就是生成so或dll文件以后的路徑很不好控制。最重要的一點Java 的C調用通常不能移植到其他平臺上,失去了“write once,run anywhere ”的美譽!但沒違反重用性的規則。再者,需求來了,不這樣實現能行嗎?

          posted on 2005-12-21 18:54 beyondduke 閱讀(1839) 評論(0)  編輯  收藏 所屬分類: 編程隨筆

          <2005年12月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導航

          統計

          公告


          MSN聯系

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          我的連接

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 扬中市| 宁夏| 临城县| 大化| 双辽市| 客服| 邓州市| 芦山县| 武川县| 乐安县| 陆河县| 阳东县| 仁布县| 元朗区| 安国市| 积石山| 深州市| 台州市| 左权县| 沈阳市| 清原| 曲松县| 兴文县| 襄樊市| 大同市| 新竹市| 渑池县| 高尔夫| 梅州市| 沧源| 白朗县| 霍城县| 建始县| 聂荣县| 阜宁县| 商水县| 剑川县| 五大连池市| 新营市| 大埔区| 中宁县|