加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

NDK开发 - JNI数组数据处理

发布时间:2021-03-07 02:17:06 所属栏目:大数据 来源:网络整理
导读:许多时辰操作 NDK 开拓都是为了对数据举办加密操纵,由于纯真的 Java 太轻易被反编译了,加密算法也就很轻易被破解,而操作 C/C++ 开拓可以加大破解难度。文件的数据加密就必要通过 byte 数组传给 JNI。 传送门: NDK开拓 - JNI数组数据处理赏罚 JNI 中的数组分
副问题[/!--empirenews.page--]

许多时辰操作 NDK 开拓都是为了对数据举办加密操纵,由于纯真的 Java 太轻易被反编译了,加密算法也就很轻易被破解,而操作 C/C++ 开拓可以加大破解难度。文件的数据加密就必要通过 byte 数组传给 JNI。

传送门:NDK开拓 - JNI数组数据处理赏罚

JNI 中的数组分为根基范例数组和工具数组,它们的处理赏罚方法是纷歧样的,根基范例数组中的全部元素都是 JNI 的根基数据范例,可以直接会见。而工具数组中的全部元素是一个类的实例或其余数组的引用,和字符串操纵一样,不能直接会见 Java 转达给 JNI 层的数组,必需选择吻合的 JNI 函数来会见和配置 Java 层的数组工具。

会见根基范例数组

Java 代码:

//挪用数组
byte array[] = {'A','B','C','D','E'};
byte[] resutl = NativeMethod.getByteArray(array);
for (int i = 0; i < array.length; i++) {
    Log.d(TAG,"ARRAY : " + array[i] + "->" + resutl[i]);
}

native 代码:

JNIEXPORT jbyteArray JNICALL Java_com_example_gnaix_ndk_NativeMethod_getByteArray
        (JNIEnv *env,jclass object,jbyteArray j_array){
    //1. 获取数组指针和长度
    jbyte *c_array = env->GetByteArrayElements(j_array,0);
    int len_arr = env->GetArrayLength(j_array);

    //2. 详细处理赏罚
    jbyteArray c_result = env->NewByteArray(len_arr);
    jbyte buf[len_arr];
    for(int i=0; i<len_arr; i++){
        buf[i] = c_array[i] + 1;
    }

    //3. 开释内存
    env->ReleaseByteArrayElements(j_array,c_array,0);

    //4. 赋值
    env->SetByteArrayRegion(c_result,len_arr,buf);
    return c_result;
}

运行功效:

NDK开拓 - JNI数组数据处理赏罚

  示例中,从 Java 层中传进去了一个数组,参数范例是 byte[],对应 JNI 中 jbyteArray 范例。操作 GetByteArrayElements 函数获取数组指针,第二个参数返回的数组指针是原始数组,照旧拷贝原始数据到姑且缓冲区的指针,假如是 JNI_TRUE:暗示姑且缓冲区数组指针,JNI_FALSE:暗示姑且原始数组指针。开拓傍边,我们并不体谅它从那边返回的数组指针,这个参数填 NULL 即可,但在获取到的指针必需做校验。
相同的函数尚有 GetIntArrayElements,GetFloatArrayElements,GetDoubleArrayElements 等。
  然后对数据举办了处理赏罚,而且开释了数组内存。ReleaseByteArrayElements 是与 GetByteArrayElements 对应行使的。

  除了上述要领还可以用 JNI 中的 GetXXArrayRegion 函数举办实现数据操纵,对应的 SetXXArrayRegion 上述也有提到过。

JNIEXPORT jint JNICALL Java_com_example_gnaix_ndk_NativeMethod_getByteArray
        (JNIEnv *env,jbyteArray j_array){
    jbyte *c_array;
    jint len_arr;

    //1. 获取数组长度
    len_arr = env->GetArrayLength(j_array);

    //2. 申请缓冲区
    c_array = (jbyte *) malloc(sizeof(jbyte) * len_arr);

    //3. 初始化缓冲区
    memset(c_array,sizeof(jbyte)*len_arr);

    //4. 拷贝java数组数据
    env->GetByteArrayRegion(j_array,c_array);

    //5. 计较总和
    int sum = 0;
    for(int i=0; i<len_arr; i++){
        sum += c_array[i];
    }

    //6. 开释缓冲区
    free(c_array);
    return sum;
}

会见引用范例数组

  JNI 提供了两个函数来会见工具数组,GetObjectArrayElement 返回数组中指定位置的元素,SetObjectArrayElement 修改数组中指定位置的元素。与根基范例差异的是,我们不能一次获得数据中的全部工具元素可能一次复制多个工具元素到缓冲区。由于字符串和数组都是引用范例,只能通过 Get/SetObjectArrayElement 这样的 JNI 函数来会见字符串数组可能数组中的数组元素。
  下面的例子同挪用 Native 要领 建设一个工具数组,返回后打印这个数组内容:

//返回工具数组
Person persons[] =  NativeMethod.getPersons();
for(Person person : persons){
    person.toString();
}

Person 类:

/**
 * 名称: Person
 * 描写:
 *
 * @author xiangqing.xue
 * @date 16/3/10
 */
public class Person {
    private String TAG = "Person";

    public String name;
    public int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String toString(){
        String result =  "Name: " + name + ",age: " + age;
        Log.d(TAG,result);
        return result;
    }
}

Native 要领:

JNIEXPORT jobjectArray JNICALL Java_com_example_gnaix_ndk_NativeMethod_getPersons
        (JNIEnv *env,jclass object){
    jclass clazz = NULL;
    jobject jobj = NULL;
    jmethodID mid_construct = NULL;
    jfieldID fid_age = NULL;
    jfieldID fid_name = NULL;
    jstring j_name;

    //1. 获取Person类的Class引用
    clazz = env->FindClass("com/example/gnaix/ndk/Person");
    if(clazz == NULL){
        LOGD("clazz null");
        return NULL;
    }

    //2. 获取类的默认结构函数ID
    mid_construct = env->GetMethodID(clazz,"<init>","()V");
    if(mid_construct == NULL){
        LOGD("construct null");
        return NULL;
    }

    //3. 获取实例要领ID和变量ID
    fid_name = env->GetFieldID(clazz,"name","Ljava/lang/String;");
    fid_age = env->GetFieldID(clazz,"age","I");
    if(fid_age==NULL || fid_name==NULL){
        LOGD("age|name null");
        return NULL;
    }

    //4. 处理赏罚单个工具并添加到数组
    int size = 5;
    jobjectArray obj_array = env->NewObjectArray(size,clazz,0);
    for(int i=0; i<size; i++){
        jobj = env->NewObject(clazz,mid_construct);
        if(jobj == NULL){
            LOGD("jobject null");
            return NULL;
        }
        env->SetIntField(jobj,fid_age,23 + i);
        j_name = env->NewStringUTF("gnaix");
        env->SetObjectField(jobj,fid_name,j_name);
        env->SetObjectArrayElement(obj_array,i,jobj);
    }


    //5. 开释局部变量
    env->DeleteLocalRef(clazz);
    env->DeleteLocalRef(jobj);
    return obj_array;
}

运行功效:

NDK开拓 - JNI数组数据处理赏罚

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读