引用数据类型的操作
1、字符串
1 // 用给定的 C 字符串创建 Java 字符串 2 jstring javaString; 3 javaString = (*env)->NewStringUTF(env, "Hello World!"); 4 5 // 将 Java 字符串转换成 C 字符串 6 const jbyte* str; 7 jboolean isCopy; 8 9 str = (*env)->GetStringUTFCharts(env, javaString, &isCopy); 10 if( 0 != str) 11 printf("Java string: %s", str); 12 13 if(JNI_TRUE == isCopy){ 14 printf("C string is a copy of the Java string."); 15 }else{ 16 printf("C string points to actual string."); 17 } 18 } 19 20 // 释放 JNI 函数返回的 C 字符串 21 (*env)->ReleaseStringUTFCharts(env, javaString, str);
2、数组
1 // 在原生代码中创建数组 2 jintArray javaArray; 3 javaArray = (*env)->NewIntArray(env, 10); 4 if( 0 != javaArray){ 5 /*现在可以使用数组了*/ 6 } 7 8 // 将 Java 数组区复制到 C 数组中 9 jint nativeArray[10]; 10 (*env)->GetIntArrayRegion(env, javaArray, 0, 10, nativeArray); 11 12 // 从 C 数组向 Java 数组提交所作的修改 13 (*env)->SetIntArrayRegion(env, javaArray, 0, 10, nativeArray); 14 15 // 获得指向 Java 数组元素的直接指针 16 jint* nativeDirectArray; 17 jboolean isCopy; 18 19 nativeDirectArray = (*env)->GetIntArrayElements(env, javaArray, &isCopy); 20 21 // 释放指向 Java 数组元素的直接指针 22 (*env)->ReleaseIntArrayElements(env, javaArray, nativeDirectArray, 0);
3、NIO 缓冲区
1 // 基于给定的 C 字节数组创建字节缓冲区 2 unsigned char* buffer = (unsigned char*)malloc(1024); 3 4 jobject direcctBuffer; 5 direcctBuffer = (*env)->NewDirecctByteBuffer(env, buffer, 1024); 6 7 // 通过 Java 字节缓冲区获取原生字节数组 8 unsigned char* buffer; 9 buffer = (unsigned char*)(*env)->GetDirectBufferAddress(env, directBuffer);
4、访问域
1 // 带有静态域和实例域的 Java 类 2 public class JavaClass{ 3 /*实例域*/ 4 private String instanceField = "Instance Field"; 5 6 /*静态域*/ 7 private static String staticField = "Static Field"; 8 } 9 10 // 用对象引用获得类 11 jclass clazz; 12 clazz = (*env)->GetObjectClass(env, instance); 13 14 // 获取实例域ID 15 jfieldID instanceFieldId; 16 instanceFieldId = (*env)->GetFieldID(env, clazz, "instanceField", "Ljava/lang/String;"); 17 18 // 获取静态域ID 19 jfieldID staticFieldId; 20 staticFieldId = (*env)->GetStaticFieldID(env, clazz, "staticField", "Ljava/lang/String;"); 21 22 // 获得实例域 23 jstring instanceField; 24 instanceField = (*env)->GetObjectField(env, instance, instanceFieldId); 25 26 // 获得静态域 27 jstring staticField; 28 staticField = (*env)->GetStaticObjectField(env, clazz, staticFieldId);
5、调用方法
1 // 带有静态方法和实例方法的 Java 类 2 public class JavaClass{ 3 4 /*实例方法*/ 5 private String instanceMethod(){ 6 return "Instance Method"; 7 } 8 9 /*静态方法*/ 10 private static String staticMethod(){ 11 return "Static Method"; 12 } 13 } 14 15 // 获取实例方法ID 16 jmethodID instanceMethodId; 17 instanceMethodId = (*env)->GetMethodID(env, clazz, "instanceMethod", "()Ljava/lang/String;"); 18 19 // 获取静态方法ID 20 jmethodID staticMethodId; 21 staticMethodId = (*env)->GetStaticMethodID(env, clazz, "staticMethod", "()Ljava/lang/String;"); 22 23 // 调用实例方法 24 jstring instanceMethodResult; 25 instanceMethodResult = (*env)->CallStringMethod(env, instance, instanceMethodId); 26 27 // 调用静态方法 28 jstring staticMethodResult; 29 staticMethodResult = (*env)->CallStaticStringMethod(env, clazz, StaticMethodId);
6、异常处理
1 // 抛出异常的 Java 类 2 public class JavaClass{ 3 4 /* 抛出方法 */ 5 private void throwingMethod() throws NullPointerException { 6 throw new NullPointerException("Null pointer"); 7 } 8 9 /* 访问方法(原生方法)*/ 10 private native void accessMethod(); 11 } 12 } 13 14 // 原生代码中的异常处理 15 jthrowable ex; 16 17 (*env)->CallVoidMethod(env, instance, throwingMethod); 18 ex = (*env)->ExceptionOccurred(env); 19 20 if( 0 != ex){ 21 (*env)->ExceptionClear(env); 22 23 /* Exception handler*/ 24 } 25 26 // 原生代码中抛出异常 27 jclass clazz; 28 29 clazz = (*env)->FindClass(env, "java/lang/NullPointerException"); 30 31 if( 0 != clazz){ 32 (*env)->ThrowNew(env, clazz, "Exception message."); 33 }
7、局部和全局引用
1 // 删除一个局部引用 2 jclass clazz; 3 clazz = (*env)->FindClass(env, "java/lang/String"); 4 5 (*env)->DeleteLocalRef(env, clazz); 6 7 // 用给定的局部引用创建全局引用 8 jclass localClazz; 9 jclass globalClazz; 10 11 localClazz = (*env)->FindClass(env, "java/lang/String"); 12 globalClazz = (*env)->NewGlobalRef(env, localClazz); 13 14 (*env)->DeleteLocalRef(env, localClazz); 15 16 // 删除一个全局引用 17 (*env)->DeleteGlobalRef(env, globalClazz); 18 19 // 用给定的局部引用创建弱全局引用 20 jclass weakGlobalClazz; 21 weakGlobalClazz = (*env)->NewWeakGlobalRef(env, localClazz); 22 23 // 检验弱全局变量是否有效 24 if(JNI_FALSE == (*env)->IsSameObject(env, weakGlobalClazz, NULL)){ 25 /* 对象仍然处于活动状态且可以使用 */ 26 }else{ 27 /* 对象被垃圾回收器收回,不能使用 */ 28 } 29 30 // 删除一个弱全局引用 31 (*env)->DeleteWeakGlobalRef(env, weakGlobalClazz);
8、同步
1 // Java 同步代码块 2 synchronized(obj){ 3 /* 同步线程安全代码块 */ 4 } 5 6 // Java 同步代码块的原生等价 7 if(JNI_OK == (*env)->MonitorEnter(env, obj)){ 8 /* 错误处理 */ 9 } 10 11 /* 同步线程安全代码块 */ 12 13 if(JNI_OK == (*env)->MonitorExit(env, obj)){ 14 /* 错误处理 */ 15 } 16 17 // 将当前线程与虚拟机附着和分离 18 JavaVM* cachedJvm; 19 JNIEnv* env; 20 21 /* 将当前线程附着到虚拟机 */ 22 (*cachedJvm)->AttachCurrentThread(cachedJvm, &env, NULL); 23 24 /* 可以用 JNIEnv 接口实现线程与 Java 应用程序的通信 */ 25 26 /* 将当前线程与虚拟机分离 */ 27 (*cachedJvm)->DetachCurrentThread(cachedJvm);

浙公网安备 33010602011771号