java 使用jni调用c++代码

流程如下:

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;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值