操作JNI函数以及复杂对象传递

在掌握了JNI函数的使用和相关类型的映射后,以及知晓何利用javah工具生成对应的jni函数以及如何生成动态

》)。即可掌握JNI的使用了了。

可都是些小例子,耐心看咯。

主要操作内容,包括如下几个部分:

1、在Native层返回一个字符串

2、从Native层返回一个int型二维数组(int a[ ][ ])

3、从Native层操作Java层的类: 读取/设置类属性

4、在Native层操作Java层的类:读取/设置类属性、回调Java方法

5、从Native层返回一个复杂对象(即一个类咯)

6、在Java层传递复杂对象至Native层

7、从Native层返回Arraylist集合对象

广而告知,这些操作就是简单的利用一些JNI函数即实现了。so easy 。

一、在Native层返回一个字符串

Java层原型方法:

public class HelloJni {…public native void getAJNIString();…}

Native层该方法实现为 :

/* * Class:com_feixun_jni_HelloJni * Method: getAJNIString * Signature: ()Ljava/lang/String; */ //返回字符串JNIEXPORT jstring JNICALL Java_com_feixun_jni_HelloJni_getAJNIString(JNIEnv * env, jobject obj){jstring str = env->newStringUTF("HelloJNI"); //直接使用该JNI构造一个jstring对象返回return str ;}

二、在Native层返回一个int型二维数组(inta[ ][ ])

Java层原型方法:

public class HelloJni {…//参数代表几行几列数组 ,形式如:int a[dimon][dimon]private native int[][] getTwoArray(int dimon) ; …} Native层该方法实现为 :/* * Class:com_feixun_jni_HelloJni * Method: getTwoArray * Signature: (I)[[I *///通过构造一个数组的数组, 返回 一个二维数组的形式JNIEXPORT jobjectArray JNICALL Java_com_feixun_jni_HelloJni_getTwoArray (JNIEnv * env, jobject object, jint dimion){jclass intArrayClass = env->FindClass("[I"); //获得一维数组 的类引用,即jintArray类型//构造一个指向jintArray类一维数组的对象数组,该对象数组初始大小为dimionjobjectArray obejctIntArray = env->NewObjectArray(dimion ,intArrayClass , NULL);//构建dimion个一维数组,,并且将其引用赋值给obejctIntArray对象数组for( int i = 0 ; i< dimion ; i++ ){//构建jint型一维数组jintArray intArray = env->NewIntArray(dimion);jint temp[10] ; //初始化一个容器,假设 dimion < 10 ;for( int j = 0 ; j < dimion ; j++){temp[j] = i + j ; //赋值}//设置jit型一维数组的值env->SetIntArrayRegion(intArray, 0 , dimion ,temp);//给object对象数组赋值,即保持对jint一维数组的引用env->SetObjectArrayElement(obejctIntArray , i ,intArray);env->DeleteLocalRef(intArray); //删除局部引用}return obejctIntArray; //返回该对象数组}三、在Native层操作Java层的类 :读取/设置类属性

Java层原型方法:

public class HelloJni {…//在Native层读取/设置属性值public native void native_set_name() ;…private String name = "I am at Java" ; //类属性} Native层该方法实现为 :/* * Class:com_feixun_jni_HelloJni * Method: native_set_name * Signature: ()V *///在Native层操作Java对象,读取/设置属性等JNIEXPORT void JNICALL Java_com_feixun_jni_HelloJni_native_1set_1name (JNIEnv *env , jobject obj ) //obj代表执行此JNI操作的类实例引用{ //获得jfieldID 以及 该字段的初始值 jfieldID nameFieldId ;jclass cls = env->GetObjectClass(obj); //获得Java层该对象实例的类引用,即HelloJNI类引用nameFieldId = env->GetFieldID(cls , "name" , "Ljava/lang/String;"); //获得属性句柄if(nameFieldId == NULL) {cout << " 没有得到name 的句柄Id \n;" ; } jstring javaNameStr = (jstring)env->GetObjectField(obj ,nameFieldId); // 获得该属性的值 const char * c_javaName = env->GetStringUTFChars(javaNameStr , NULL); //转换为 char *类型 string str_name = c_javaName ;cout << "the name from java is " << str_name << endl ; //输出显示 env->ReleaseStringUTFChars(javaNameStr , c_javaName); //释放局部引用//构造一个jString对象 char * c_ptr_name = "I come from Native" ;jstring cName = env->NewStringUTF(c_ptr_name); //构造一个jstring对象env->SetObjectField(obj , nameFieldId , cName); // 设置该字段的值}

却还是,会愚蠢的选择相互敌视的方式。即使背脊相抵,

操作JNI函数以及复杂对象传递

相关文章:

你感兴趣的文章:

标签云: