java調用C/C++寫的dll

來源:互聯網
上載者:User

標籤:

源:java調用C/C++寫的dll

  Java語言本身具有跨平台性,如果通過Java調用DLL的技術方便易用,使用Java開發前台介面可以更快速,也能帶來跨平台性。

Java調用C/C++寫好的DLL庫時,由於基礎資料型別 (Elementary Data Type)不同、使用位元組序列可能有差異,所以在參數傳遞過程中容易出現問題,DLL中可能需要做相應的轉換。

使用Java調用DLL動態連結程式庫的方案通常有三種:JNI, Jawin, Jacob. 其JNI(Java Native Interface)是Java語言本身提供的調用本地已編譯的函數庫的方法,本身具有跨平台性,可以在不同的機器上調用不同的本地庫。Jawin和Jacob都是sourceforge.net的開源項目,都是基於JNI技術的依賴Windows的實現,使得在Windows平台下使用COM和DLL的更加方便。

    下面,我們來詳細介紹一下使用JNI來實現Java與C/C++之間的調用。

 

一、  JNI簡介

JNI是Java Native Interface的縮寫。從Java 1.1開始,Java Native Interface(JNI)標準成為java平台的一部分,它允許Java代碼和其他語言寫的代碼進行互動。JNI一開始是為了本地已編譯語言,尤其是C和C++而設計的,但是它並不妨礙你使用其他語言,只要呼叫慣例受支援就可以了。

sun相關文檔:http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/jniTOC.html

 

二、  簡單步驟

 

第一步:

編寫Java類,用該類將DLL對外提供的函數服務進行聲明,其中的Java方法均聲明為native,其方法簽名可以自訂,不用實現函數體。一個例子如下:DllTest.java

public class DllTest

{

     static

     {

         System.loadLibrary("chat");

     }

 

     public static native int connect(int i);

     public static native String getstring(String src);

 

     public static void main(String[] args)

     {

         DllTest dllTest = new DllTest();

         System.out.println(dllTest.connect(5));

         System.out.println(dllTest.getstring("java send"));

     }

}

其中,chat為該動態庫的名字,它的副檔名字可以不用寫出來,究竟是DLL還是SO,由系統自己判斷。在這裡,定義了兩個介面函數,一個是具有int型的入參和傳回值的connect函數,一個是具有String字串對象的入參和傳回值的getstring函數。他們都不需要具體的實現。 

 

第二步:

用Javah工具將該Java類產生對應的.h標頭檔。首先,用javac DllTest.java編譯成DllTest.class 檔案,然後用 javah DllTest 編譯出一個 DllTest.h 檔案。這個DllTest.h即是C/C++動態庫中的標頭檔,C/C++程式需要實現它。DllTest.h 的標頭檔內容:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class DllTest */

 

#ifndef _Included_DllTest

#define _Included_DllTest

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     DllTest

 * Method:    connect

 * Signature: (I)I

 */

JNIEXPORT jint JNICALL Java_DllTest_connect

  (JNIEnv *, jclass, jint);

 

/*

 * Class:     DllTest

 * Method:    getstring

 * Signature: (Ljava/lang/String;)Ljava/lang/String;

 */

JNIEXPORT jstring JNICALL Java_DllTest_getstring

  (JNIEnv *, jclass, jstring);

 

#ifdef __cplusplus

}

#endif

#endif

這裡JNIEXPORT和JNICALL都是JNI的關鍵字,表示此函數是要被JNI調用的。而jint、jstring是以JNI為中介使JAVA中的資料類型與C/C++中的資料類型之間的一種中間類型。Jint可以直接當做int使用,但是jstring不能和char *等同,需要做一定的轉換。函數的名稱是JAVA_再加上java程式的package路徑再加函數名組成的。參數中,我們也只需要關心在JAVA程式中存在的參數,至於JNIEnv*和jclass我們一般沒有必要去碰它。

 

第三步:

編寫C/C++代碼實現.h標頭檔中聲明的函數,該C/C++代碼中包含jni.h標頭檔。

int i = 2;

const char *teststr = "c/c++ return";

 

JNIEXPORT jint JNICALL Java_DllTest_connect

(JNIEnv *, jclass, jint j)

{

     i = i + j;

     return i;

}

 

JNIEXPORT jstring JNICALL Java_DllTest_getstring

(JNIEnv * env, jclass, jstring policy)

{

     // jstring 轉換為char * (utf-8)

     const char * s1 = env->GetStringUTFChars(policy, false);

     printf("%s/n", s1);

 

     // char * (utf-8) 轉換為jstring

     jstring js = env->NewStringUTF(teststr); 

     return  js;

}

然後用C/C++的編譯工具編譯產生char.dll動態庫。把這個動態庫放到第二步中的DllTest.class所在的檔案夾中。

 

第四步:

用java DllTest 執行調用,你就可以看到輸出結果:

7

Java send

c/c++ return

 

java調用C/C++寫的dll(轉)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.