java 调用c代码_JNI Java调用C代码 示例

#include

#include

#include//必须添加的头文件

#include

#include"com_bqt_hellofromc_MyNativeMethods.h"//引入生成的头文件,注意要把此文件放在jni文件夹中,src目录下的此文件不需要了

//在C中使用log,除在此声明外,还需在Android.mk文件中增加【LOCAL_LDLIBS += -llog】

#include//引入log头文件

#defineLOG_TAG "bqt"// 这个是自定义的LOG的标识

//定义一些输出的LOG函数

#defineLOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG ,__VA_ARGS__) // 定义LOGD类型

#defineLOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG ,__VA_ARGS__) // 定义LOGI类型

#defineLOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG ,__VA_ARGS__) // 定义LOGW类型

#defineLOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG ,__VA_ARGS__) // 定义LOGE类型

#defineLOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG ,__VA_ARGS__) // 定义LOGF类型

//******************************************************************************************【1】返回一个字符串

JNIEXPORT jstring JNICALL Java_com_bqt_hellofromc_MyNativeMethods_helloFromC(JNIEnv *env, jobject obj) {

//写成【JNIEnv * env】或【JNIEnv *env】或【JNIEnv*env】都可以。【返回值】【方法名】【参数列表】返回值类型jstring就是java中的string

char* cstr = "hello from c"; //  char*  在c中可用来表示一个字符串。注意,这里绝对不能有中文

jstring jstr = (*env)->NewStringUTF(env, cstr);

return jstr;

}

//******************************************************************************************【2】返回int类型计算后的结果

JNIEXPORT jint JNICALL Java_com_bqt_hellofromc_MyNativeMethods_passwordFromC(JNIEnv * env, jobject obj, jint a, jint b) {

return a + b + 10000; //c中的int占用字节数在不同环境下可能不同,可能是0-65535,所以,稍微大一点的数(十万级别)都得用double

}

//******************************************************************************************【3】对给定字符串进行处理,模拟加密运算

JNIEXPORT jstring JNICALL Java_com_bqt_hellofromc_MyNativeMethods_encodeFromC(JNIEnv * env, jobject obj, jstring passwd, jint length) {

//char* cstr = Jstring2CStr2(env, passwd); //将java的字符串转化为c语言。卧槽这方法编译不通过,估计是因为找不到一些库之类的东西的原因!

//    int i = 0;

//    for (i = 0; i 

//        *(cstr + i) += 1; //给C语言字符加1

//    }

char* cstr = "abc";

return (*env)->NewStringUTF(env, cstr); //将c语言字符串转化为java字符串

}

//******************************************************************************************【4】对给定数组进行操作,模拟多媒体解码

JNIEXPORT jintArray JNICALL Java_com_bqt_hellofromc_MyNativeMethods_intMethod(JNIEnv * env, jobject jobject, jintArray arr) {

int len = (*env)->GetArrayLength(env, arr); // 获取数组的长度

LOGI("ArrayLength=%d", len);

//LOG中也不能有中文

jint* p = (*env)->GetIntArrayElements(env, arr, 0); //取出数组中第一个元素的内存地址

//If isCopy is not NULL, then *isCopy is set to JNI_TRUE if a copy ismade; if no copy is made, it is set to JNI_FALSE.

int i = 0;

for (; i 

LOGI("before-%d-=%d", i, *(p+i));

//这一步没问题,会一个个打印所有数组中的内容

*(p + i) += 5; //取出的每个元素加5

LOGI("after-%d-=%d", i, *(p+i));

//这一步也没问题,会一个个打印处理后的内容

}

jint* elems = (*env)->GetIntArrayElements(env, arr, 0); //再次获取元素的内存地址

LOGI("ok-%d-=%d", i, *elems);

//但返回的为啥还是未经处理的?

//重新创建一个数组

jintArray array = (*env)->NewIntArray(env, len); //Construct构造 a new primitive array object基本数组对象

int ii = 0;

int jj;

for (; ii 

jj = 10000 + ii;

(*env)->SetIntArrayRegion(env, array, ii, 1, &jj); //Sets the value of one element in a primitive array.其中【&】代表【取地址】操作,而非逻辑操作

//(*env)->SetIntArrayRegion(env,array,【start】,【len】,buffer) , 从start开始复制长度为len 的数据 buffer到 array 中

}

return array;

}

//******************************************************************************************【工具方法】把java的字符串转换成c的字符串

char* Jstring2CStr(JNIEnv* env, jstring jstr) {

char* rtn = NULL;

//1:先找到字节码文件

jclass clsstring = (*env)->FindClass(env, "Java/lang/String"); //Java或java都一样

jstring strencode = (*env)->NewStringUTF(env, "GB2312"); //和UTF-8不行

//2:通过字节码文件找到方法ID

jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");

//3:通过方法id,调用方法

jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode); // String .getByte("GB2312");

//4:得到数据的长度

jsize alen = (*env)->GetArrayLength(env, barr);

//5:得到数据的首地址

jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);

//6:得到C语言的字符串

if (alen > 0) {

rtn = (char*) malloc(alen + 1); //"\0"

memcpy(rtn, ba, alen);

rtn[alen] = 0;

}

(*env)->ReleaseByteArrayElements(env, barr, ba, 0); //

return rtn;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值