本地方法调用2_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 本地方法调用2

本地方法调用2

 2012/6/11 0:11:50  nanapoleon  程序员俱乐部  我要评论(0)
  • 摘要:这次来介绍一下,带参数和返回值的jni调用。因为c的int你无法知道他是多少位的,可能16可能32,当然,在java平台上int总是32位的。基于这个原因,java本地接口定义了jint、jlong等类型。boolean=jboolean字节为1byte=jbyte字节为1char=jchar字节为2.....在头文件jni.h中,这些类型被typedef语句声明为在目标平台上等价的类型。该头文件也定义了常量JNI_FALSE=0,JNI_TRUE=1。所以,当你在java层传入的int
  • 标签:方法
    这次来介绍一下,带参数和返回值的jni调用。
    因为c的int你无法知道他是多少位的,可能16可能32,当然,在java平台上int总是32位的。基于这个原因,java本地接口定义了jint、jlong等类型。
boolean = jboolean 字节为1
byte = jbyte 字节为1
char = jchar 字节为2
.....
    在头文件jni.h中,这些类型被typedef语句声明为在目标平台上等价的类型。该头文件也定义了常量JNI_FALSE=0,JNI_TRUE=1。
    所以,当你在java层传入的int, long等类型,经过javah的转换,到下面都以jintjlong的形势展现。
    这里面,还有一个很常用的类型需要单独考虑,那就是string类型。
在Java中,字符串是UTF-16编码点的序列,而c的字符串则是以null结尾的字节序列,所以这两种语言中的字符串差别很大。
    Java本地接口有两组操作字符串的函数,一组把java字符串转换成“改良的UTF8”字节序列,另一组将他们转化成UTF-16数值的数组,也就是说转换成jchar数组。
    JNI函数有一个有些古怪的调用约定,下面是对NewStringUTF函数的一个调用:
JNIEXPORT jstring JNICALL Java_HelloNative_getGreeting(JNIEnv* env, jclass cl){
    jstring jstr;
    char greeting[] = "Hello, Native World\n";
    jstr = (*env)->NewStringUTF(env, greeting);
    return jstr;
}

    所有对JNI函数的调用都引用到了env指针,该指针是每一个本地方法的第一个参数。env指针是函数指针表的指针。所以,你必须在每个JNI调用前面加上(*env)->,以便实际上取消对函数指针的引用。而且,env是每个JNI函数的第一个参数。
(C++注意: C++中队JNI函数的访问要简单一些。JNIEnv类的C++版本有一个内敛成员函数,它负责帮你查找函数指针,例如,你可以这样调用NEWStringUTF函数:
jstr = env->NewStringUTF(greeting);
注意,这里从该调用的参数列表里删除了JNIEnv指针。

    接着string编码来看,两种编码的jstring编码方法,使用两个函数来得到:NewStringUTF(JNIEnv* env, const char bytes[])newString(JNIEnv* env, const jchar chars[], jsize length)
    而getStringUTF(当然UTF-16对应的是const jchar* getStringChars()方法,后面的方法就不一一对应了,可以查资料找到)函数可以用来读取一个jstring对象的内容。该函数返回指向描述字符串的“改良UTF-8”字符的const jbyte*指针。注意,具体的虚拟机可以自由地选择该编码来表示它内部的字符串,所以,你也许可以得到实际的JAVA字符串的字符指针。因为Java字符串是不可变的,所以慎重处理const很重要,不要试图将数据写到该字符数组中。不过,如果虚拟机使用UTF-16或UTF-32字符作为其内部字符串的表示,那么该函数会分配一个新的内存块来存储等价的“改良UTF-8”编码字符。
    还有一个问题,虚拟机必须知道你何时使用完字符串,这样它就能进行垃圾回收(垃圾回收器是在一个独立线程中运行的,它能够中断本地方法的执行)。所以,我们必须调用RealeaseStringUTFChars函数。
    另外,可以通过调用GetStringRegionGetStringUTFRegion方法来提供你自己的缓存,来存放字符串的字符。
    最后GetStringUTFLength函数返回编码字符串所需的“改良UTF-8”字符个数。
    书上有例子,有api,网上也能查到,剩下的方法就不多说了,下次分析一下这两个编码方式吧。
发表评论
用户名: 匿名