转 J2SE:JNI:JAVA调用已经存在的动态连接库(dll)
来源:互联网 发布:鱼眼校正软件 编辑:程序博客网 时间:2024/05/12 15:51
有时候吧,一个项目不是由单一的某种语言构成的,所以避免不了语言与语言之间的协作关系。
比如:这时你的项目部分是用JAVA编写的,你需要对数据进行加密与解密的操作,一般来说你会用JAVA实现一个加密算法。不过呢,现在你手头上有个非JAVA的组件可以用,比如DLL,考虑到效率上的问题你使用这个DLL更好些。这时候你就得使用JNI(JAVA NATIVE INTERFACE)—JAVA 原生接口。
这样我们从一个JAVA调用一个存在的DLL例子入手吧。
DES.dll 调用接口如下:
然后,编译(这里不叙述),生成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
这个就是我们要得到的头文件。
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"
//加密
编译,生成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代码,声明原生函数和参数。
public class JDES {
/**
* Kaede
*/
static{
System.loadLibrary("com_daxiannetwork_util_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);
}
}
//声明的原生函数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);
#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);
* 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头文件有什么差别,}
#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);
(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);
strcpy(mingwen,OutputStr);
//告诉VM本地代码不在有权使用UTF
env->ReleaseStringUTFChars(cryptograph, T_cryptograph);
env->ReleaseStringUTFChars(key, T_key);
delete [] OutputStr;
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);
(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);
strcpy(miwen,OutputStr);
env->ReleaseStringUTFChars(proclaim, T_proclaim);
env->ReleaseStringUTFChars(key, T_key);
delete [] OutputStr;
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
- 转 J2SE:JNI:JAVA调用已经存在的动态连接库(dll)
- J2SE:JNI:JAVA调用已经存在的动态连接库(dll)
- JNI java调用动态链接库dll
- Java通过JNI调用DLL动态库
- Java调用DLL动态链接库的JNI方式详解
- 【JNI调用DLL动态库】Java使用JNI调用DLL动态链接库学习记录
- Java调用C/C++编写的动态连接库-JNI
- [转]Java调用DLL动态链接库的方案:JNI, Jawin, Jacob.
- Java Jni 调用动态链接库总结 dll文件
- java jni 调用动态链接库dll函数
- eclipse上java项目通过jni调用dll动态库
- java使用JNI调用DLL动态库错误
- Java通过JNI 调用动态链接库DLL
- JAVA(JNI,Jnative,JNA)分别调用delphi的动态链接库(dll)的技术交流.
- 关于java用jni调用 dll动态库Can't find dependent libraries错误的解决
- JAVA(JNI,Jnative,JNA)分别调用delphi的动态链接库(dll)
- 关于java用jni调用 dll动态库Can't find dependent libraries错误的解决
- Java使用JNI调用C/C++的DLL动态链接库1
- 用实体关系图进行数据库建模
- 发现bash真的可以像vi一样使用,终于统一了
- 简单继承UserDetails
- 关于Oracle中select * from where 的存储过程
- Mercury QuickTestProfessional 9.0试用版下载
- 转 J2SE:JNI:JAVA调用已经存在的动态连接库(dll)
- id,name区别
- 简单背包问题(实际上是子集问题)
- echo 打印彩色字符
- 向DataTable表中添加一行空信息,使DropDownList的第一个选项为空
- 海空神佛的虚伪[注意]
- 充分利用ASP.NET的三种缓存提高站点性能
- 通用ODBC API应用结构概述
- mx