流程如下:
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; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)