有时候吧,一个项目不是由单一的某种语言构成的,所以避免不了语言与语言之间的协作关系。
比如:这时你的项目部分是用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 { /** public native String Decrypt(String cryptograph,String key); |
然后,编译(这里不叙述),生成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" /* #ifdef __cplusplus |
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,加入以下代码,如下。
JNIEXPORT jstring JNICALL Java_com_daxiannetwork_util_JDES_Decrypt void * objptr = CreateDES_Dll(); char * OutputStr = new char[1000]; char mingwen[1000]; int result = Decrypt(objptr,OutputStr,T_cryptograph,T_key); //告诉VM本地代码不在有权使用UTF env->ReleaseStringUTFChars(cryptograph, T_cryptograph); env->ReleaseStringUTFChars(key, T_key); return env->NewStringUTF(mingwen);
JNIEXPORT jstring JNICALL Java_com_daxiannetwork_util_JDES_Encrypt 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 中的一个方法。 env->ReleaseStringUTFChars(key, T_key); 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,呵呵 文章写的不好。见谅!!
有问题这里问就好了,我经常来的。