流程如下:
1、使用eclipse建立一个java工程,建立一个java文件,在这里我只写了一个方法,myadd()。
package com.imgMatch;//包名影响着javah的使用
public class ForDll
{
static
{
System.loadLibrary("javaCallcpp");//javaCallcpp就是要加载的dll的名字,这是相对路径加载方式
}
public native int myadd(int a , int b);//myadd就是要在dll中实现的方法
public static void main(String args[])
{
ForDll test = new ForDll();
System.out.println(test.myadd(5, 6));
}
}
2.1、 命令行里面 javac ForDll.java 生成ForDll.class
2.2 继续,javah 生成.h,这是给C++用的。
注意,命令应该是(这里注意路径)
javah -classpath . -jni com.xx.xx
3、打开VS2015,建立一个win32控制台程序,这里选dll
4.1 将com_imgMatch_ForDll.h加入dll工程之中
4.2 在dll工程中新建一个TestJNI.cpp,内容如下:
#include "com_imgMatch_ForDll.h"
JNIEXPORT jint JNICALL Java_imgMatch_ForDll_myadd(JNIEnv *env, jobject obj, jint a, jint b) {
return a+b;
}
4.3 由于需要java sdk中的jni头文件,还需要在dll工程配置中引入
5、编译通过,生成dll文件,注意看是需要32位的还是64位的dll(jdk的版本),否则运行的时候会出错
6、 在java项目里面添加dll
选中该项目,右键属性,在java build path里面的Libraries里面,打开JRE System Lib,里面的Native lib location,选择你放dll的文件夹即可
7、运行结果如下,提醒一点:如果javaCallcpp这个dll还依赖了xxx.dll时,还需要先System.loadLibrary其他的dll,否则也会报错
static {
System.loadLibrary("xxx");
System.loadLibrary("javaCallcpp");
}
8、C++ dll中一些调用的函数写法
首先定义号方法cipher.h
class cipher {
public:
static int aes_encrypt(unsigned char *in, unsigned char *key, int ketLen, unsigned char *out);
static int aes_decrypt(unsigned char *in, unsigned char *key, int keyLen, unsigned char *out);
static char *Base64encode(const void *pin, int inlen, char *pout, char bNewLine = 1);
static void Base64decode(const char *pin, void *pout, int *poutLen, char bNewLine = 1);
};
java方法定义
public native String AesEncode(String content, String key);
public native String AesDecode(String content, String key);
那么相应的我们在jni中就需要定义下面两个方法
extern "C"
JNIEXPORT jstring JNICALL
Java_com_dds_openssl_OpenCipher_AesEncode(JNIEnv *env, jobject thiz,
jstring _content,
jstring _key)
extern "C"
JNIEXPORT jstring JNICALL
Java_com_dds_openssl_OpenCipher_AesDecode(JNIEnv *env, jobject thiz,
jstring _content,
jstring _key)
示例代码
extern "C"
JNIEXPORT jstring JNICALL
Java_com_dds_openssl_OpenCipher_AesDecode(JNIEnv *env, jobject thiz,
jstring _content,
jstring _key) {
LOGD("------------encrypt----------------");
const char *content = env->GetStringUTFChars(_content, JNI_FALSE);
int contentLen = env->GetStringLength(_content);
const char *key = env->GetStringUTFChars(_key, JNI_FALSE);
int keyLen = env->GetStringLength(_key);
LOGD("dec content:%s", content);
LOGD("dec key:%s", key);
int encLen = 0;
unsigned char *pEncData = (unsigned char *) malloc(contentLen);
// base64解密
cipher::Base64decode(content, pEncData, &encLen, false);
LOGD("dec base64 hex :%s", char2HexStr(pEncData, encLen).c_str());
int dataLen = encLen + 1;
unsigned char *pData = (unsigned char *) malloc(dataLen);
memset(pData, 0, dataLen);
// ase 解密
if (cipher::aes_decrypt(pEncData, (unsigned char *) key, keyLen, pData) <= 0) {
free(pEncData);
free(pData);
env->ReleaseStringUTFChars(_content, content);
env->ReleaseStringUTFChars(_key, key);
return NULL;
}
pData[dataLen] = 0;
LOGD("dec aes:%s", pData);
jstring jStr = env->NewStringUTF((const char *) (pData));
free(pEncData);
free(pData);
env->ReleaseStringUTFChars(_content, content);
env->ReleaseStringUTFChars(_key, key);
return jStr;
}
int cipher::aes_decrypt(unsigned char *in, unsigned char *key, int keyLen, unsigned char *out) {
AES_KEY aes;
if (!in || !key || !out) return 0;
// 检查key长度
if (keyLen != 16 && keyLen != 24 && keyLen != 32) {
LOGE("aes_decrypt key length is invalid");
return -1;
}
// 设置key
if (AES_set_decrypt_key(key, keyLen << 3, &aes) != 0) { // keyLen*8
LOGE("aes_decrypt AES_set_decrypt_key error");
return -2;
}
AES_ecb_encrypt(in, out, &aes, AES_DECRYPT);
return 1;
}