JNI学习之步步深入三

来源:互联网 发布:模拟2g3g4g网络测试 编辑:程序博客网 时间:2024/04/26 01:17

上一篇中,学习了jni中的类型映射关系。本篇就一个简单点的实例来看看java端的类型,如何被C端识别。同时,在C端实现定义的一个类型

如何传递到java端。本篇以String类型为例,看看java端的unicode编码的String类型如何和C端utf-8编码的char*类型进行交互!

 


 

 

1、首先,在java端写一个Prompt类:其中定义一个getLine方法,他含有一个String类型的参数,同时,返回String类型。

[java] view plaincopy
  1. package demo.jni;  
  2. public class Prompt {  
  3.       
  4.     //传递给一个String对象  
  5.     private native String getLine(String str);  
  6. }  

 

2、生成头文件,这里略。。。

 

3、编写C端:讲解在注释中了

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include "demo_jni_Prompt.h"  
  4. JNIEXPORT jstring JNICALL Java_demo_jni_Prompt_getLine  
  5.   (JNIEnv *env, jobject clazz, jstring prompt)  
  6. {  
  7.      /**java中String类型的prompt这里,被转换成了jni中的一个类型jstring。 
  8.      ***那么这个jstring类型,我们可以直接cout输出吗?答案是否定的。 
  9.      ***我们知道在java中字符采用的是Unicode编码,在c/c++中,字符使用UTF-8编码 
  10.      ***我们不需要深入了解Unicode和UTF-8两种编码的具体方法和内容。我们只需要知道 
  11.      ***Unicode采用的是16-bit编码,而UTF-8采用的是7-bit编码的,所以,我们需要 
  12.      ***完成这一转换工作,jni已经提供了相应的接口,如下:  
  13.      **/  
  14.      char buf[128] = "我是从本地代码获取到的"//字符缓冲  
  15.      jbyte *str;//jbyte类型对应C中的unsigned char   
  16.      str = (*env)->GetStringUTFChars(env, prompt, NULL); //这个函数就是将jstring类型的字符串转换为本地字符串,返回jbyte*类型  
  17.      if(str == NULL)  
  18.      {  
  19.          /** 
  20.             GetStringUTFChars方法可能会抛出一个OutOfMemoryError的异常,在jni中的异常机制和java中的并不一样 
  21.             在java中抛出异常,如果没有捕获,则程序结束运行;但是,在jni中,即使抛出异常,在本地代码的执行顺序依然不变。 
  22.             所以,这里判断NULL是必须的  
  23.          **/   
  24.          return NULL;  
  25.            
  26.      }  
  27.      printf("%s",str);  
  28.      /** 
  29.      **使用完了utf-8类型的字符后,我们需要释放由上面方法返回的字符串,这样可以释放被这些字符占用的内存空间,避免造成内存瘫痪  
  30.      **/  
  31.      (*env)->ReleaseStringUTFChars(env, prompt, str);  
  32.        
  33.      //下面我们看看如何将本地的代码传到java  
  34.        
  35.      return (*env)->NewStringUTF(env, buf);  //该方法实例化一个UTF-8编码的本地字符串为java.lang.String类型,新创建的就是java中  
  36.      //Unicode类型的代表同一字符串的实例  
  37.      //该方法同样可能抛出一个OutOfMemoryError的异常并返回NULL。   
  38.             
  39. }  
  40.    

 

可以看到,在生成的本地方法中,原来的String类型的prompt被替换成了jstring。jni提供了GetStringUTFChars方法供我们,将jstring读取到本地。同时提供了NewStringUTF方法,让我们将本地的类型传递到java端。

 

同理,对于其他的类型,比如数组等,操作也是类似,只是所使用的方法不同而已。



0 0
原创粉丝点击