引用数据类型的操作

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);

 

posted @ 2015-07-02 19:01  壬子木  阅读(209)  评论(0)    收藏  举报