Java与JNI类型转换,方法调用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qiantanlong/article/details/78650296
算是Java和JNI的数据类型转换和方法的调用,算是基本工具类吧,没有详细整理。




//
// Created by hongzhen on 2017/11/24.
//
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <android/log.h>
#include <stdio.h>
#include "../include/hongzhen_com_jnitypeturn_JNITypeTurnUtils.h"
/* Header for class wentsai_hisign_com_testlibrary_TestUtils */
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,"Yu" ,__VA_ARGS__) // 定义LOGI类型
#ifdef __cplusplus
extern "C" {
#endif

typedef struct TestBean{
    unsigned char isBoolen;
    char isByte;
    char isChar;
    short isShort;
    int isInt;
    long isLong;
    float isFloat;
    double isDouble;
    char *isString;

    unsigned char *isBoolens;
    char  *isBytes;
    char *isChars ;
    short *isShorts;
    int *isInts;
    long *isLongs;
    float *isFloats;
    double *isDoubles;
} *testBean;

/*JNIEXPORT void JNICALL Java_wentsai_hisign_com_testlibrary_TestUtils_getStudent
        (JNIEnv *env, jclass jclas, jobject jobj) {
    jclass js = (*env)->GetObjectClass(env, jobj);
    jfieldID jidname = (*env)->GetFieldID(env, js, "name", "Ljava/lang/String;");
    jstring jstr = (*env)->GetObjectField(env, jobj, jidname);
    char *name = (*env)->GetStringUTFChars(env, jstr, NULL);
    LOGI("Name----%s", name);
    jfieldID jidage = (*env)->GetFieldID(env, js, "age", "I");
    jint age = (*env)->GetIntField(env, jobj, jidage);
    LOGI("Age----%d", age);
    jmethodID jmid_say = (*env)->GetMethodID(env, js, "say", "()V");
    (*env)->CallVoidMethod(env, jobj, jmid_say);
    jstring new_jstr = (*env)->NewStringUTF(env, "LiTang");
    (*env)->SetObjectField(env,jobj,jidname,new_jstr);
}*/

void Jni2Java(JNIEnv *env, jobject jobj){
    //Jni类型转Java类型
    jclass jclas = (*env)->GetObjectClass(env, jobj);

    //--------------------------------------------------------
    //boolean型变量
    jfieldID fid_boolean = (*env)->GetFieldID(env, jclas, "isBoolen", "Z");
    jboolean jb =JNI_FALSE;
    (*env)->SetBooleanField(env,jobj,fid_boolean,jb);

    //--------------------------------------------------------
    //byte型变量 isByte
    jfieldID fid_byte = (*env)->GetFieldID(env, jclas, "isByte", "B");
    jbyte my_byte=44;
    (*env)->SetByteField(env,jobj,fid_byte,my_byte);

    //--------------------------------------------------------------------------
    //char/short/float/double/long/与上面的一样

    //--------------------------------------------------------------------------
    //string
    jfieldID fid_string = (*env)->GetFieldID(env, jclas, "isString", "Ljava/lang/String;");
    jstring jstr=(*env)->NewStringUTF(env,"王佳");;
    (*env)->SetObjectField(env,jobj,fid_string,jstr);

    //-------------------------------------------------------------------------------------
    //byte[]
    //获取fieldID
    jfieldID fid_bytes=(*env)->GetFieldID(env,jclas,"isBytes","[B");
    //准备数据
    char my_bytes[5]={1,2,3,4,5};
    //创建jbyteArray
    jbyteArray my_byte_arrsy=(*env)->NewByteArray(env,5);
    //将数据放入到jbyteArray
    (*env)->SetByteArrayRegion(env,my_byte_arrsy,0,5,my_bytes);
    //将jbyteArray存入到对应类的变量中
    (*env)->SetObjectField(env,jobj,fid_bytes,my_byte_arrsy);

    //--------------------------------------------------------------------------------------
    //int[]
    jfieldID jid_int_array=(*env)->GetFieldID(env,jclas,"isInts","[I");
    int my_ints[5]={11,22,3,34,35};
    jintArray my_int_array=(*env)->NewIntArray(env,5);
    (*env)->SetIntArrayRegion(env,my_int_array,0,5,my_ints);
    (*env)->SetObjectField(env,jobj,jid_int_array,my_int_array);
}


/**
 * Java类型的变量向jni类型转换
 * @param env
 * @param jobj
 */
void java2Jni(JNIEnv *env, jobject jobj) {
    //Java类型转jni类型
    jclass jclas = (*env)->GetObjectClass(env, jobj);


    //--------------------------------------------------------
    //boolean型变量
    jfieldID fid_boolean = (*env)->GetFieldID(env, jclas, "isBoolen", "Z");
    if (fid_boolean == NULL) {
        LOGI("Boolen---%s", "null");
    }
    jboolean jbool = (*env)->GetBooleanField(env, jobj, fid_boolean);
    if (jbool) {
        LOGI("Boolen---%s", "true");
    }
    //--------------------------------------------------------
    //byte型变量 isByte
    jfieldID fid_byte = (*env)->GetFieldID(env, jclas, "isByte", "B");
    if (fid_byte == NULL) {
        LOGI("Byte---%s", "null");
    }
    jbyte jfield_byte = (*env)->GetByteField(env, jobj, fid_byte);
    LOGI("Byte---%d", jfield_byte);
    char c_char=jfield_byte;
    LOGI("c_char---%d", c_char);//存储的是数值,以%d输出,如果以%c输出会没有结果

    //--------------------------------------------------------------------
    //char型变量
    jfieldID fid_char = (*env)->GetFieldID(env, jclas, "isChar", "C");
    if (fid_char == NULL) {
        LOGI("Byte---%s", "null");
    }
    jchar jfield_char = (*env)->GetCharField(env, jobj, fid_char);
    LOGI("Byte---%c", jfield_char);

    char c_char1=jfield_char;
    LOGI("c_char1---%c", c_char1);

    //-----------------------------------------------------------------------------
    //Short
    jfieldID fid_short = (*env)->GetFieldID(env, jclas, "isShort", "S");
    jshort jfield_shor=(*env)->GetShortField(env,jobj,fid_short);
    LOGI("Short---%d", jfield_shor);

    //-------------------------------------------------------------------------------
    //int
    jfieldID fid_int=(*env)->GetFieldID(env,jclas,"isInt","I");
    jint jfield_ing=(*env)->GetIntField(env,jobj,fid_int);
    LOGI("Int---%d", jfield_ing);

    //-------------------------------------------------------------------------------
    //long
    jfieldID fid_long=(*env)->GetFieldID(env,jclas,"isLong","J");
    if (fid_long==NULL){
        LOGI("Long---%s", "null");
    }
    jlong jfield_long=(*env)->GetLongField(env,jobj,fid_long);
    LOGI("Long---%ld", jfield_long);

    //----------------------------------------------------------------------------------
    //float
    jfieldID fid_float=(*env)->GetFieldID(env,jclas,"isFloat","F");
    jfloat jfield_float=(*env)->GetFloatField(env,jobj,fid_float);
    LOGI("Float---%f", jfield_float);

    //-----------------------------------------------------------------------------------
    //double
    jfieldID fid_double=(*env)->GetFieldID(env,jclas,"isDouble","D");
    jdouble jfield_double=(*env)->GetDoubleField(env,jobj,fid_double);
    LOGI("Double---%f", jfield_double);

    //-------------------------------------------------------------------------------------
    //String
    jfieldID fid_string = (*env)->GetFieldID(env, jclas, "isString", "Ljava/lang/String;");
    jstring jfield_string = (*env)->GetObjectField(env, jobj, fid_string);
    char *name = (*env)->GetStringUTFChars(env, jfield_string, NULL);
    LOGI("String----%s", name);

    //-------------------------------------------------------------------------------------
    //byte[]
    jfieldID fid_bytes=(*env)->GetFieldID(env,jclas,"isBytes","[B");
    jbyteArray jfield_byte_array=(*env)->GetObjectField(env,jobj,fid_bytes);
    int size=(*env)->GetArrayLength(env,jfield_byte_array);
    //GetByteArrayRegion--进行值拷贝,将Java端数组的数据拷贝到本地的数组中
    char arr[size];
    (*env)->GetByteArrayRegion(env,jfield_byte_array,0,size,arr);
    int i;
    for ( i = 0; i < size; ++i) {
        LOGI("Byte---%d", arr[i]);
    }
    //GetByteArrayElements--指针的形式,将本地的数组指针直接指向Java端的数组地址,其实本质上是JVM在
    // 堆上分配的这个数组对象上增加一个引用计数,保证垃圾回收的时候不要释放,从而交给本地的指针使用,
    // 使用完毕后指针一定要记得通过ReleaseByteArrayElements进行释放,否则会产生内存泄露
    jbyte *byte_array=(*env)->GetByteArrayElements(env,jfield_byte_array,JNI_FALSE);
    int j;
    for ( j = 0; j < size; ++j) {
        LOGI("Byte---%d", *byte_array);
        byte_array++;
    }
    (*env)->ReleaseByteArrayElements(env,jfield_byte_array,byte_array,JNI_COMMIT);

    //--------------------------------------------------------------------------------------
    //int[]
    jfieldID jid_int_array=(*env)->GetFieldID(env,jclas,"isInts","[I");
    jintArray jfield_int_array=(*env)->GetObjectField(env,jobj,jid_int_array);
    int size_int=(*env)->GetArrayLength(env,jfield_int_array);
    //GetByteArrayRegion--进行值拷贝,将Java端数组的数据拷贝到本地的数组中
    int ints[size_int];
    (*env)->GetIntArrayRegion(env,jfield_int_array,0,size_int,ints);
    int a;
    for ( a = 0; a < size_int; ++a) {
        LOGI("Ints---%d", ints[i]);
    }

    //GetByteArrayElements--指针的形式,将本地的数组指针直接指向Java端的数组地址,其实本质上是JVM在
    // 堆上分配的这个数组对象上增加一个引用计数,保证垃圾回收的时候不要释放,从而交给本地的指针使用,
    // 使用完毕后指针一定要记得通过ReleaseByteArrayElements进行释放,否则会产生内存泄露
    jint *int_array=(*env)->GetIntArrayElements(env,jfield_int_array,JNI_FALSE);
    int s;
    for ( s = 0; s < size_int; ++s) {
        LOGI("Ints---%d", *int_array);
        int_array++;
    }
    (*env)->ReleaseIntArrayElements(env,jfield_int_array,int_array,JNI_COMMIT);

    //---------------------------------------------------------------------------------
    //其他类型的数组转换,跟byte[] ,int[]是一样的
    //对应签名:Object[]-[Ljava/lang/object;
    //          boolean[]-[B}
    //          char[]-[C
    //          short[]-[S
    //          long[]-[J
    //          float[]-[F
    //          double[]-[D

    //---------------------------------------------------------------------------------------
    //访问静态属性
    jfieldID jfid=(*env)->GetStaticFieldID(env,jclas,"staticInt","I");
    jint statcInt=(*env)->GetStaticIntField(env,jclas,jfid);
    LOGI("静态属性%d",statcInt);

    //---------------------------------------------------------------------------------------
    //访问Java方法
    jmethodID methid=(*env)->GetMethodID(env,jclas,"getIsInt","()I");
    jint result=(*env)->CallIntMethod(env,jobj,methid);
    LOGI("普通方法%d",result);

    //---------------------------------------------------------------------------------------
    //访问Java静态方法
    jmethodID md=(*env)->GetStaticMethodID(env,jclas,"getAge","()I");
    jint age=(*env)->CallStaticIntMethod(env,jclas,md);
    LOGI("静态方法%d",age);


}
JNIEXPORT void JNICALL Java_hongzhen_com_jnitypeturn_JNITypeTurnUtils_getTest
        (JNIEnv *env, jclass jclas, jobject jobj){
    java2Jni(env,jobj);
    Jni2Java(env,jobj);


}
#ifdef __cplusplus
}
#endif

猜你喜欢

转载自blog.csdn.net/qiantanlong/article/details/78650296