J2SE:JNI:JAVA調用已經存在的動態串連庫(dll)

來源:互聯網
上載者:User

        有時候吧,一個項目不是由單一的某種語言構成的,所以避免不了語言與語言之間的協作關係。
比如:這時你的項目部分是用JAVA編寫的,你需要對資料進行加密與解密的操作,一般來說你會用JAVA實現一個密碼編譯演算法。不過呢,現在你手頭上有個非JAVA的組件可以用,比如DLL,考慮到效率上的問題你使用這個DLL更好些。這時候你就得使用JNI(JAVA NATIVE INTERFACE)—JAVA 原生介面。

        這樣我們從一個JAVA調用一個存在的DLL例子入手吧。

                         DES.dll  調用介面如下:

1、 加密

I=Encrypt(對象,密文, 明文, 密鑰)

I=1時加密成功;I=0時加密失敗 ;I為整型變數

函數:int   Encrypt(void * objptr,char* OutBuffer,LPSTR DataInBuffer,LPSTR KeyInBuffer)

 

輸入參數:

CString DataInBuffer,要加密的明文

CString KeyInBuffer 加密金鑰

       要求:8-16個字元,(實際範圍0-16字元)

輸出參數:

char* OutBuffer, 加密後的密文

                     格式:(明文字元數/8+1)*16

2、 解密

I=Decrypt(對象,原文,密文, 密鑰)

I=1時加密成功;I=0時加密失敗 ;I為整型變數

函數:int Decrypt(void * objptr,char * OutBuffer,LPSTR DataInBuffer,LPSTR KeyInBuffer)

輸入參數:

CString DataInBuffer,要解密的密文

       無格式要求

CString KeyInBuffer 解密密鑰

要求:8-16個字元,(實際範圍0-16字元)

輸出參數:

char* OutBuffer, 解密後的明文

                      格式:原文字串

3、對象

void * CreateDES_Dll()

        首先,實現一個JAVA代碼,聲明原生函數和參數。

package com.daxiannetwork.util;

public class JDES {

    /**
     * Kaede
     */
    static{
          
        System.loadLibrary("com_daxiannetwork_util_JDES");
        
    }

    public native String Decrypt(String cryptograph,String key);
    //聲明的原生函數Decrypt,用於解密
    public native String Encrypt(String proclaim,String key);
    //聲明的原生函數Encrypt,用於加密

    public static void main(String[] args) {

        JDES jdes=new JDES();
        
        String a=jdes.Encrypt("123","1")
        //1為密鑰
        String b=jdes.Encrypt(a,"1");

        System.out.println(a+":"+b);

            }
}

                       然後,編譯(這裡不敘述),產生JDES.class。
                       接下來,用javah.exe產生C的標頭檔。
                      這個必須說一下,由於我們這個類包含在com.daxiannetwork.util中。
                       

javah -jni -d D:/eclipse/workspace/GUI/com/daxiannetwork/util com.daxiannetworkt.util.JDES

                        在這個目錄下D:/eclipse/workspace/GUI/com/daxiannetwork/util 有一個com_daxiannetwork_util_JDES.h
這個就是我們要得到的標頭檔。
                           

#include "jni.h"
#ifndef _Included_com_daxiannetwork_util_JDES
#define _Included_com_daxiannetwork_util_JDES
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_daxiannetwork_util_JDES
 * Method:    Decrypt
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_daxiannetwork_util_JDES_Decrypt
  (JNIEnv *, jobject, jstring, jstring);

/*
 * Class:     com_daxiannetwork_util_JDES
 * Method:    Encrypt
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_daxiannetwork_util_JDES_Encrypt
  (JNIEnv *, jobject, jstring, jstring);

#ifdef __cplusplus
}
#endif
#endif

看看,跟正常的C標頭檔有什麼差別,
JNIEXPORT jstring JNICALL Java_com_daxiannetwork_util_JDES_Encrypt (JNIEnv *, jobject, jstring, jstring);
JNIEXPORT,JNICALL這是宏,將被展開為平台專有的指令。JNIEnv , jobject, jstring, jstring 都是
JNI定義的資料類型。
Java_com_daxiannetwork_util_JDES_Encrypt 這個是函數名,所有的原生函數都以Java作為標識,後面是包名方法名。呵呵,這樣使得C++代碼必須實現這樣的方法,可是原有的dll函數不是這樣的,
所以我採用java—>yourDLL—>otherDLL。

現在我們來實現自己的DLL吧!
用VC++建立一個com_daxiannetwork_util_JDES MFC 動態串連庫的項目(由於已經存在的DLL是用MFC實現的),然後將%JAVA_HOME%/include與%JAVA_HOME%/include/win32下的.h檔案加入到項目中,
接著,修改VC++項目產生的com_daxiannetwork_util_JDES.h,將JAVAH產生的.h檔案用記事本開啟、複製
所有內容,粘貼到VC++項目產生的com_daxiannetwork_util_JDES.h,最前面。
實現這個本地函數,開啟com_daxiannetwork_util_JDES.cpp,加入以下代碼,如下。

#include "com_daxiannetwork_util_JDES.h"

//將調用的DLL標頭檔
#include "DES_DLL_I.h"

JNIEXPORT jstring JNICALL Java_com_daxiannetwork_util_JDES_Decrypt
   (JNIEnv *env, jobject obj, jstring cryptograph,jstring key) {
    
 const char *T_cryptograph = env->GetStringUTFChars(cryptograph, 0);
    
 const char *T_key = env->GetStringUTFChars(key, 0);

    void * objptr = CreateDES_Dll();

 char * OutputStr = new char[1000];

    char mingwen[1000];

 int result = Decrypt(objptr,OutputStr,T_cryptograph,T_key);
   
    strcpy(mingwen,OutputStr);

    //告訴VM本地代碼不在有權使用UTF

 env->ReleaseStringUTFChars(cryptograph, T_cryptograph);

    env->ReleaseStringUTFChars(key, T_key);
   
 delete [] OutputStr;

 return env->NewStringUTF(mingwen);
 }

//加密

JNIEXPORT jstring JNICALL Java_com_daxiannetwork_util_JDES_Encrypt
   (JNIEnv *env, jobject obj, jstring proclaim,jstring key) {
   
 const char *T_proclaim = env->GetStringUTFChars(proclaim, 0);
    
 const char *T_key = env->GetStringUTFChars(key, 0);

    void * objptr = CreateDES_Dll();//調用other dll 中的一個方法。

 char * OutputStr = new char[1000];

    char miwen[1000];

 int result = Encrypt(objptr,OutputStr,T_proclaim,T_key);//調用other dll 中的一個方法。
    
    strcpy(miwen,OutputStr);

 env->ReleaseStringUTFChars(proclaim, T_proclaim);

 env->ReleaseStringUTFChars(key, T_key);
   
 delete [] OutputStr;

  return env->NewStringUTF(miwen);
 }

編譯,產生com_daxiannetwork_util_JDES.dll,然後將這兩個DLL註冊到PATH中。
 運行程式。

呵呵,這個介紹了調用第3方的DLL,但是不適合出學者。其實都是一樣的,就是JDES.class與com_daxiannetwork_util_JDES.dll溝通。

將紫色部分去掉就是只有JDES.class與com_daxiannetwork_util_JDES.dll溝通了,呵呵,就是直來直去。

呵呵,關於JNI更詳細的請見:
http://java.sun.com/j2se/1.3/docs/guide/jni/spec/jniTOC.doc.html

JNI調用已經存在的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.