有时候吧,一个项目不是由单一的某种语言构成的,所以避免不了语言与语言之间的协作关系。
比如:这时你的项目部分是用JAVA编写的,你需要对数据进行加密与解密的操作,一般来说你会用JAVA实现一个加密算法。不过呢,现在你手头上有个非JAVA的组件可以用,比如DLL,考虑到效率上的问题你使用这个DLL更好些。这时候你就得使用JNI(JAVA NATIVE INTERFACE)—JAVA 原生接口。
这样我们从一个JAVA调用一个存在的DLL例子入手吧。
DES.dll 调用接口如下:
然后,编译(这里不叙述),生成JDES.class。
接下来,用javah.exe生成C的头文件。
这个必须说一下,由于我们这个类包含在com.daxiannetwork.util中。
在这个目录下D:/eclipse/workspace/GUI/com/daxiannetwork/util 有一个com_daxiannetwork_util_JDES.h
这个就是我们要得到的头文件。
看看,跟正常的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,加入以下代码,如下。
编译,生成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,呵呵 文章写的不好。见谅!!
比如:这时你的项目部分是用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 |
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,呵呵 文章写的不好。见谅!!
有问题这里问就好了,我经常来的。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=253333