本地方法调用2

这次来介绍一下,带参数和返回值的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的转换,到下面都以[color=red]jint[/color],[color=red]jlong[/color]的形势展现。
这里面,还有一个很常用的类型需要单独考虑,那就是string类型。
在Java中,字符串是[color=red]UTF-16[/color]编码点的序列,而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调用前面加上[color=red](*env)->[/color],以便实际上取消对函数指针的引用。而且,env是每个JNI函数的第一个参数。
(C++注意: C++中队JNI函数的访问要简单一些。JNIEnv类的C++版本有一个内敛成员函数,它负责帮你查找函数指针,例如,你可以这样调用NEWStringUTF函数:
jstr = env->NewStringUTF(greeting);
注意,这里从该调用的参数列表里删除了JNIEnv指针。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值