《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 嵌入式技術(shù) > 設(shè)計(jì)應(yīng)用 > 基于Java程序調(diào)用VC++中的DLL的研究與應(yīng)用
基于Java程序調(diào)用VC++中的DLL的研究與應(yīng)用
來源:微型機(jī)與應(yīng)用2014年第6期
孫文華, 劉 平
(南昌工程學(xué)院 信息工程學(xué)院,江西 南昌 330099)
摘要: 隨著計(jì)算機(jī)普及率的提升以及軟件行業(yè)的飛速發(fā)展,計(jì)算機(jī)語(yǔ)言也越來越受到廣大計(jì)算機(jī)愛好者和計(jì)算機(jī)軟件開發(fā)人員的關(guān)注。同時(shí)越來越多的服務(wù)要求跨平臺(tái)的實(shí)現(xiàn)。當(dāng)前比較流行的兩大語(yǔ)言VC++和Java幾乎可以開發(fā)所有基于B/S架構(gòu)和基于C/S架構(gòu)的軟件項(xiàng)目。它們各有所長(zhǎng),如果能將Java和VC有效地結(jié)合起來,實(shí)現(xiàn)二者的互相調(diào)用,那將可以取長(zhǎng)補(bǔ)短,同時(shí)可以避免許多重復(fù)的工作,提高編程的效率。
關(guān)鍵詞: 軟件 JAVA VC DLL MFC 漢字編碼
Abstract:
Key words :

摘   要: 隨著計(jì)算機(jī)普及率的提升以及軟件行業(yè)的飛速發(fā)展,計(jì)算機(jī)語(yǔ)言也越來越受到廣大計(jì)算機(jī)愛好者和計(jì)算機(jī)軟件開發(fā)人員的關(guān)注。同時(shí)越來越多的服務(wù)要求跨平臺(tái)的實(shí)現(xiàn)。當(dāng)前比較流行的兩大語(yǔ)言VC++和Java幾乎可以開發(fā)所有基于B/S架構(gòu)和基于C/S架構(gòu)的軟件項(xiàng)目。它們各有所長(zhǎng),如果能將Java和VC有效地結(jié)合起來,實(shí)現(xiàn)二者的互相調(diào)用,那將可以取長(zhǎng)補(bǔ)短,同時(shí)可以避免許多重復(fù)的工作,提高編程的效率。
關(guān)鍵詞: Java; VC; DLL; MFC; 漢字編碼

    雖然Java和VC++是當(dāng)前兩大主流的編程語(yǔ)言,但是如果兩者之間不能有效結(jié)合,實(shí)現(xiàn)相互調(diào)用的話,勢(shì)必會(huì)給編程人員的工作帶來諸多不便,增加許多的重復(fù)工作,甚至有可能造成整個(gè)項(xiàng)目的擱淺。另外,不同語(yǔ)言之間的互相調(diào)用還可以有效地利用現(xiàn)有程序,并且不需要一遍一遍地撰寫類似的程序代碼。為此,本文引人了VC++中的動(dòng)態(tài)鏈接庫(kù)文件,通過實(shí)例闡述了如何在Java中成功調(diào)用VC++動(dòng)態(tài)鏈接庫(kù)的問題[1]。
1 技術(shù)介紹
1.1 動(dòng)態(tài)鏈接庫(kù)DLL

    動(dòng)態(tài)鏈接庫(kù)DLL好比一個(gè)封裝起來的“倉(cāng)庫(kù)”,DLL是Dynamic Link Library的縮寫,其中封裝了一些或者部分可以被共享的例程和資源,采用動(dòng)態(tài)的連接方式就能夠被其他程序動(dòng)態(tài)裝載、運(yùn)行以完成某些特定的功能。
    采用動(dòng)態(tài)鏈接庫(kù)進(jìn)行軟件開發(fā),具體優(yōu)勢(shì)主要有下面幾點(diǎn):
 (1)對(duì)硬件資源方面的要求比較小
 在程序開發(fā)過程中,經(jīng)常遇到多個(gè)程序調(diào)用同一個(gè)函數(shù)庫(kù)的情況,這時(shí)如果使用動(dòng)態(tài)鏈接庫(kù),就可以大大減少在磁盤和物理內(nèi)存中重復(fù)代碼的加載。只有當(dāng)生成的EXE 文件確實(shí)要調(diào)用該DLL模塊時(shí),系統(tǒng)才會(huì)將其加載到內(nèi)存空間中去。
 (2)項(xiàng)目體系結(jié)構(gòu)模塊化開發(fā)
    程序結(jié)構(gòu)模塊化對(duì)項(xiàng)目開發(fā)有著重要的作用,能夠方便項(xiàng)目的管理與功能的定制。動(dòng)態(tài)鏈接庫(kù)的設(shè)計(jì)包含這種思想。另外,動(dòng)態(tài)鏈接庫(kù)支持多語(yǔ)言。這樣可以有更廣闊的應(yīng)用平臺(tái),方便開發(fā)程序的移植,也可以在不同的開發(fā)平臺(tái)上調(diào)用。通常當(dāng)開發(fā)的系統(tǒng)為龐大系統(tǒng),避免不了有許多重復(fù)類型的功能,這時(shí)如果將這些類似的功能單獨(dú)做成DLL,將可以大大減少開發(fā)的工作量和提高開發(fā)的速度[2]。
    (3)軟件維護(hù)方便
    當(dāng)動(dòng)態(tài)鏈接庫(kù)中的函數(shù)需要更新或修復(fù)時(shí),采用動(dòng)態(tài)鏈接庫(kù)更方便。因?yàn)椴渴鸺鞍惭b動(dòng)態(tài)鏈接庫(kù)在此就不要求重新建立程序與該DLL 的連接。此外,如果多個(gè)程序使用同一個(gè)DLL,則多個(gè)程序都將從該更新或修復(fù)中獲益。當(dāng)使用定期更新或修復(fù)的第三方DLL 時(shí),此問題可能會(huì)更頻繁地出現(xiàn),升級(jí)到DLL 就可以更容易解決這些問題。
 (4)功能實(shí)現(xiàn)的細(xì)節(jié)隱藏
    考慮到一些重要技術(shù)的保密和知識(shí)產(chǎn)權(quán)的保護(hù),在某些情況下,通常將項(xiàng)目中一些功能實(shí)現(xiàn)的具體細(xì)節(jié)隱藏起來,即希望里面的部分代碼不被公開,這時(shí)動(dòng)態(tài)鏈接庫(kù)就是一項(xiàng)非常不錯(cuò)的實(shí)現(xiàn)方法。動(dòng)態(tài)鏈接庫(kù)可以被其他應(yīng)用程序訪問調(diào)用,但將代碼的具體細(xì)節(jié)完全隱藏起來。另外,DLL的語(yǔ)言無關(guān)性也是很重要的一個(gè)方面。正是由于動(dòng)態(tài)鏈接庫(kù)DLL與語(yǔ)言無關(guān)的這個(gè)特點(diǎn),故用VC++創(chuàng)建的DLL可以被其他任何支持動(dòng)態(tài)鏈接庫(kù)的編程語(yǔ)言調(diào)用, 比如VB、Delphi、PD[3]等。
1.2 Java本地編程接口JNI
    JNI(Java Native Interfacejava)其實(shí)就是指Java本地程序接口,屬于JDK中的一部分。當(dāng)Java程序中有需要調(diào)用通過VC++語(yǔ)言編寫的DLL時(shí),此時(shí)最佳選擇就是使用JNI技術(shù)。通過使用Java本地接口書寫程序,可以確保代碼在不同的開發(fā)平臺(tái)上方便移植。JNI使得運(yùn)行于Java虛擬機(jī)的代碼可以操作用C、C++或者匯編等書寫的應(yīng)用程序或庫(kù),同時(shí)也可以通過調(diào)用相應(yīng)的接口函數(shù)將Java虛擬機(jī)內(nèi)嵌到本地應(yīng)用程序中。
    特別需要提醒的是,只要有下面幾種情況中的任何一種出現(xiàn)時(shí),程序員就需要利用JNI來進(jìn)行處理:(1)所開發(fā)的應(yīng)用程序要使用到與平臺(tái)相關(guān)的屬性, 但Java標(biāo)準(zhǔn)類庫(kù)不支持對(duì)這些屬性的處理; (2)已經(jīng)擁有了利用其他編程語(yǔ)言實(shí)現(xiàn)的應(yīng)用程序或庫(kù),希望用Java 直接調(diào)用這些應(yīng)用程序或庫(kù)來實(shí)現(xiàn); (3)程序中的某個(gè)模塊對(duì)運(yùn)行的時(shí)間效率要求很高,此時(shí)希望用比較低級(jí)的語(yǔ)言(如匯編)來實(shí)現(xiàn),同時(shí)希望在Java應(yīng)用程序中使用這個(gè)模塊[4]。
2 設(shè)計(jì)與實(shí)現(xiàn)
2.1 設(shè)計(jì)步驟

    使用JNI在Java中調(diào)用VC++寫的DLL有以下幾個(gè)步驟:(1)創(chuàng)建Java類;(2)編譯Java代碼并生成頭文件;(3)開發(fā)DLL并實(shí)現(xiàn)方法;(4)編譯動(dòng)態(tài)鏈接庫(kù);(5)測(cè)試運(yùn)行程序。
2.2 設(shè)計(jì)實(shí)例
2.2.1 無包情況

    (1)在Java中寫調(diào)用VC的代碼,具體如下:
    public class JieCheng{
        static{
        System.loadLibrary("JieCheng");
           //注意:不寫擴(kuò)展名,名字要與DLL的文件名一致
     }
    public native static int jiecheng(int n); //聲明native方法
    public static void main(String args[]){
    int s;
    JieCheng jc=new JieCheng();
    s=jc.jiecheng(5);
    System.out.println(s);                            //聲明main法
    }
    }
    (2)在運(yùn)行彈出的輸入框中輸入cmd進(jìn)入dos界面,通過cd命令進(jìn)入到安裝Java的路徑下面的bin中,假設(shè)安裝目錄是D:\Program Files\Java\jdk1.6.0_10\bin,把JieCheng.java文件移到D:\Program Files\Java\jdk1.6.0_10
\bin目錄下,輸入javac JieCheng.java,可以看到在該目錄下生成了JieCheng.class的文件。輸入javah JieCheng生成了JieCheng.h文件。具體如下:
    #include <jni.h>
    /* Header for class JieCheng */
    #ifndef _Included_JieCheng
    #define _Included_JieCheng
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     JieCheng
     * Method:    jiecheng
     * Signature: (I)I
    */
    JNIEXPORT jint JNICALL Java_JieCheng_jiecheng
          (JNIEnv *, jclass, jint);
    #ifdef __cplusplus
    }
    #endif
    #endif
    (3)在VC下創(chuàng)建DLL文件,名字一定要是System.loadLibrary("JieCheng")中的JieCheng,把JieCheng.h文件直接復(fù)制到該VC文件下,同時(shí)把jni.h,jni_md.h復(fù)制到VC工程下。在JieCheng.cpp文件下實(shí)現(xiàn)在Java中聲明過的方法,注意方法名一定要與JieCheng.h中聲明的方法一致,在方法中寫入代碼如下:
    #include"JieCheng.h"
    JNIEXPORT jint JNICALL Java_JieCheng_jiecheng(JNIEnv *,    jclass, jint n)
    {
    int i,s;
    s=1;
    for(i=1;i<=n;i++){
        s=s*i;}
    return s;
    }
    (4)在VC下編譯生成JieCheng.dll文件,把該文件直接復(fù)制到Java的安裝目錄下面的bin目錄下:D:\Program Files\Java\jdk1.6.0_10\bin。
    (5)把在VC下編譯生成的JieCheng.dll文件直接復(fù)制到Java的安裝目錄的bin目錄下:D:\Program Files\Java\jdk1.6.0_10\bin。運(yùn)行命令:java JieCheng,本例中,JieCheng函數(shù)用于求一個(gè)數(shù)的階乘,所以在屏幕上顯示的結(jié)果是“120”。
2.2.2 有包情況

 


    有包的情況與上面介紹的無包情況大致相同。但需要特別強(qiáng)調(diào)、引起注意的地方是:首先需要在Java的安裝目錄bin下創(chuàng)建包名文件夾,假設(shè)創(chuàng)建的包名文件夾的名稱為NegerVector,然后把.java文件放在此文件夾中。接下來就是進(jìn)入DOS環(huán)境下運(yùn)行兩個(gè)命令,首先運(yùn)行:javac NegerVector\ JieCheng.java;然后運(yùn)行:javah  Neger Vector.JieCheng。其他的可以參照無包情況了,因?yàn)榻酉聛砼c無包的情況基本相同。
    在許多大型項(xiàng)目的開發(fā)過程中,從提高開發(fā)效率以及實(shí)現(xiàn)代碼重用的角度來看,跨平臺(tái)服務(wù)的開發(fā)是未來的發(fā)展趨勢(shì),從而經(jīng)常需要在Java程序中調(diào)用VC中的DLL。本文從JNI技術(shù)出發(fā),通過簡(jiǎn)單的實(shí)例詳細(xì)闡述了JNI調(diào)用VC++寫的DLL的程序,解決了Java與VC的有效結(jié)合,實(shí)現(xiàn)了它們之間的相互調(diào)用。
參考文獻(xiàn)
[1] 王志文,夏秦,李平均.Java程序設(shè)計(jì)(修訂本)[M].西安:西安交通大學(xué)出版社,2005.
[2] 孫文華.一種基于Java編程的臟字過濾器的設(shè)計(jì)[J].微型機(jī)與應(yīng)用,2012,31(9):18-19,23.
[3] 王敏,邵定宏,陸金桂.動(dòng)態(tài)鏈接庫(kù)技術(shù)及其應(yīng)用實(shí)[J].微計(jì)算機(jī)信息,2006,22(27):272-274.
[4] 宋曉字,王永會(huì). Visual C++高級(jí)編程技術(shù)與實(shí)例[M].北京:中國(guó)水利水電出版社,2006.

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。