JNI学习笔记(四)——JAVA与C的数据传递

2016-10-20  本文已影响0人  熊雅慧

目标:创建一个android项目,实现以下三个方法:
public native int add(int x ,int y);//传递两个int型的变量给C,返回两数之和
public native String sayHelloInC(String s);//传递一个String的变量给C,返回一个加工过的String
public native int[] intMethod(int[] iNum); //传递一个int型的数组给C,返回一个每个数组元素都加了10的数组。

//两数相加
JNIEXPORT jint JNICALL Java_com_example_jni_1passdate_MainActivity_add
(JNIEnv * env, jobject obj, jint x, jint y){
//因为x和y都是jint类型的,所以不需要转换,直接返回x+y;
    return x+y;
}
// 工具方法   将java字符串 转换成 c字符串
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;
}

//字符串处理
JNIEXPORT jstring JNICALL Java_com_example_jni_1passdate_MainActivity_Hello
(JNIEnv * env, jobject obj, jstring js){
        //将java字符串转换成c的字符串
    char *str1 =Jstring2CStr(env,js);
    char * str2= "  你好";
    strcat(str1,str2);//字符串拼接函数
                           // 参数1: 长度必须能够包含合并后 字符串的长度的大小
                               //参数1是拼接后的字符串,参数2还是原来的参数2
    return (**env).NewStringUTF(env,str1);
}
//数组处理
JNIEXPORT jintArray JNICALL Java_com_example_jni_1passdate_MainActivity_arrAdd
(JNIEnv * env, jobject obj, jintArray jintArr){
    //Java把int数组给c语言, c语言把数组的元素+10,返回给java

    jint len = (**env).GetArrayLength(env, jintArr);//得到数组的长度

    //    jint*       (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
    /*  得到数组中的元素
     *  jintArray 指定数组
     *  jboolean* JNI_TRUE 1  复制   JNI_FALSE 0 不复制(引用)
     *  返回值: 返回数组的首地址
     * */
    jint* arr = (**env).GetIntArrayElements(env, jintArr, 0);
    int i=0;
    for( ; i < len; i++){
        *(arr+i) += 10; //(开发时使用)

        //    void        (*SetIntArrayRegion)(JNIEnv*, jintArray, jsize, jsize, const jint*);
        /* 指定一段范围内 intArray元素的值
         * JNIEnv* jni上下文对象
         * jintArray java中传递过来的数组
         * jsize 范围起始位置
         * jsize 范围的长度
         * const jint* 指定的数据
         * */

        //      int temp = *(arr + i) + 10;
        //      (**env).SetIntArrayRegion(env, jintArr, i, 1, &temp);
    }

    return jintArr;

}

static{
System.loadLibrary("Hello");
}

补充:

用到的几个方法

上一篇 下一篇

猜你喜欢

热点阅读