1. 程式人生 > >java呼叫VC編譯而成的dll檔案

java呼叫VC編譯而成的dll檔案

在JAVA中呼叫VC編寫的程式,JAVA提供一個本地方法,交給VC去實現,就是相當JAVA的介面與實現, 只不過中間的介面實現是VC實現的。

從而更好的實現了跨平臺的實用。

在Vc中建立一個空的dll工程,裡面什麼檔案也沒有,目的是Vc編譯生成的是DLL檔案,而不是EXE,注意一些設定,如果有些設定不對,則JAVA在載入你的dll檔案時會出錯。

然後把JAVA生成的一個.h檔案拷到VC的專案中,作為VC程式的一個頭檔案,另外JDK路徑下的include資料夾下拷貝出來就可以了,分別是: jni.h 和 include 下的 win32\jni_md.h檔案也都拷到vc專案中

JAVA專案中需匯入一個jnative.jar包

下面我寫一個例子:

JAVA:

package com.sinosoft;

public class LoadDll {
    static {
        //動態載入dll到類庫,注意:這裡的dll路徑必須為絕對路徑
        System.load("E:\\loadDllName.dll");
        
        //此處直接載入的是環境變數path路徑下dll檔案 ,注意:直接是dll檔案的名字,不是”loadDllName.dll“
        System.loadLibrary("loadDllName");
    }
    
    //宣告一個本地方法,此方法java中不需要去實現 , 只要宣告就可以
    //此方法是交由VC實現,相當於JAVA中宣告一個介面
    public native static void getPrintDocument();
    
}

編譯成.class檔案後

生成.h檔案,供VC標頭檔案使用

執行cmd進入dos視窗,進入剛才編譯生成位元組碼.class檔案的目錄

然後輸入javah -classpath . -jni com.sinosoft.LoadDll     其中 “.“表示當前目錄

生成的檔案com_sinosoft_LoadDll.h,內容為

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_sinosoft_LoadDll */

#ifndef _Included_com_sinosoft_LoadDll
#define _Included_com_sinosoft_LoadDll
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_sinosoft_LoadDll
 * Method:    getPrintDocument
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_sinosoft_LoadDll_getPrintDocument
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

注意:匯入的.h檔案不要更改裡面的內容,否則可能會出問題。如果在VC中開啟com_sinosoft_LoadDll.h檔案的 “#include <jni.h>” 報錯,說明你dll專案的配置不正確

其中的引數JNIEnv *, jclass 是系統生成的 ,可以不用管

裡面的方法JNIEXPORT void JNICALL Java_com_sinosoft_LoadDll_getPrintDocument
  (JNIEnv *, jclass);就是由Vc實現

VC中的test.cpp實現這個函式:
#include "com_sinosoft_LoadDll.h"

JNIEXPORT void JNICALL Java_com_sinosoft_LoadDll_getPrintDocument
  (JNIEnv *, jclass);
{
     
}

編譯生成loadDllName.dll檔案

將loadDllName.dll檔案給JAVA呼叫即可