J2SE:JNI:JAVA调用已经存在的动态连接库(dll)

        有时候吧,一个项目不是由单一的某种语言构成的,所以避免不了语言与语言之间的协作关系。
比如:这时你的项目部分是用JAVA编写的,你需要对数据进行加密与解密的操作,一般来说你会用JAVA实现一个加密算法。不过呢,现在你手头上有个非JAVA的组件可以用,比如DLL,考虑到效率上的问题你使用这个DLL更好些。这时候你就得使用JNI(JAVA NATIVE INTERFACE)—JAVA 原生接口。

        这样我们从一个JAVA调用一个存在的DLL例子入手吧。

                         DES.dll  调用接口如下:

1、 加密

IEncrypt(对象,密文, 明文, 密钥)

I1时加密成功;I0时加密失败 I为整型变量

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

 

输入参数:

CString DataInBuffer,要加密的明文

CString KeyInBuffer 加密密钥

       要求:816个字符,(实际范围016字符)

输出参数:

char* OutBuffer, 加密后的密文

                     格式:(明文字符数/8+1)*16

2、 解密

IDecrypt(对象,原文,密文, 密钥)

I1时加密成功;I0时加密失败 I为整型变量

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

输入参数:

CString DataInBuffer,要解密的密文

       无格式要求

CString KeyInBuffer 解密密钥

要求:816个字符,(实际范围016字符)

输出参数:

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,呵呵 文章写的不好。见谅!!

有问题这里问就好了,我经常来的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值