JNI中java传递各类型参数给C

  • java传递各类型参数给C的要点在于要将传递过来的数据类型转换成C认识的数据类型,C返回时又要转换成java认识的数据类型。下图是java和C数据类型的对比表。
    这里写图片描述

这里写图片描述

传递int类型数据

  • 对比前面两个表,得知java中int就是c中的jint,并且两种数据类型都是占4个字节,因此可不用转换,直接计算并返回。

Java代码:

public native int add(int x, int y);

C中实现代码:

JNIEXPORT jint JNICALL Java_com_zhong_jnipassdata_JNI_add
  (JNIEnv * env, jobject clazz, jint x, jint y){
    return x+y;
}

传递String类型数据

  • 由于String类型c并不认识,所以要将string类型转换成char类型,这里需要用到一个将string转换成char的算法。然后再将char类型转换成string类型返回给java。
  • 将string转换成char的算法。
**
 * 把一个jstring转换成一个c语言的char* 类型.
 */
char* _JString2CStr(JNIEnv* env, jstring jstr) {
     char* rtn = NULL;
     jclass clsstring = (*env)->FindClass(env, "java/lang/String");
     jstring strencode = (*env)->NewStringUTF(env,"GB2312");
     jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");
     jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode); // String .getByte("GB2312");
     jsize alen = (*env)->GetArrayLength(env, barr);
     jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
     if(alen > 0) {
        rtn = (char*)malloc(alen+1); //"\0"
        memcpy(rtn, ba, alen);
        rtn[alen]=0;
     }
     (*env)->ReleaseByteArrayElements(env, barr, ba,0);
     return rtn;
}
  • java代码
public native String sayHelloInC(String str);
  • c代码
JNIEXPORT jstring JNICALL Java_com_zhong_jnipassdata_JNI_sayHelloInC
  (JNIEnv * env, jobject clazz, jstring jstr){
    //将jstring类型转换成c中的char类型
    char* str = _JString2CStr(env,jstr);
    //得到字符串的长度
    int length = strlen(str);
    int i ;
    //改变一下字符串的值
    for (i = 0; i < length; i++) {
        *(str+i) += 2;
    }
    //将c中char类型转换成java中的string类型返回
    return (*env) -> NewStringUTF(env,str);
}

传递整型数组

  • java代码
public native int[] passArray(int[] intArray);
  • c代码
JNIEXPORT jintArray JNICALL Java_com_zhong_jnipassdata_JNI_passArray
  (JNIEnv * env, jobject clazz, jintArray array){
    //得到数组长度
    jsize length = (*env)->GetArrayLength(env,array);
    //输出log
    LOGI("数组的长度:%d",length);
    //得到数组首地址
    jint* firstPointer = (*env)->GetIntArrayElements(env,array,NULL);
    int i = 0;
    for ( i= 0;  i< length; i++) {
        //让数组中每个值都加上10
        *(firstPointer+i) += 10;
    }

    return array;
}

在c代码中使用logcat

  • Android.mk文件增加以下内容
    LOCAL_LDLIBS += -llog

  • C代码中增加以下内容

#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
  • C代码中使用logcat, 例:
LOGI("info\n,%d",length);
LOGD("debug\n");
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值