JNI_Z_09_Java的字符串
ZC: jstring 就是 Java中的String对象
ZC: 10.8 Unicode字符串结尾(http://www.360doc.cn/article/14233282_321497569.html)
从GetStringChars和GetStringCritical两个方法获得的Unicode字符串不是以NULL结尾的,需要调用GetStringLength来获取字符串的长度。一些操作系统,如Windows NT中,Unicode字符串必须以两个'\0'结尾,这样的话,就不能直接把GetStringChars得到的字符串传递给Windows NT系统的API,而必须复制一份并在字符串的结尾加入两个'\0'
ZC: http://www.360doc.cn/article/14233282_321497569.html
“
GetStringChars和ReleaseStringChars获取以Unicode格式编码的字符串。当操作系统支持Unicode编码的字符串时,这些方法很有用。
UTF-8字符串以’\0’结尾,而Unicode字符串不是。如果jstring指向一个Unicode编码的字符串,为了得到这个字符串的长度,可以调用GetStringLength。如果一个jstring指向一个UTF-8编码的字符串,为了得到这个字符串的字节长度,可以调用标准C函数strlen。或者直接对jstring调用JNI函数GetStringUTFLength,而不用管jstring指向的字符串的编码格式。
”
ZC: 个人偏好的统一做法(不管是UTF8还是Unicode) : C++中分配内存 + GetStringRegion/GetStringUTFRegion复制内存 (ZC: ∵结尾非"\0\0"的问题)
字符串操作:
A、生成一个jstring对象
jstring (JNIEnv *)->NewString(const jchar* jstr , int size); // ZC: 第一个参数 : UTF-8编码的字符串指针 和 Unicode(UTF-16)编码的宽字符串指针,都可以?它能自动适应?
ZC: jstring (JNIEnv *)->NewStringUTF(const char* _pchar); // ZC: 这个函数应该 较少用到
B、获取字符串的长度:
jsize (JNIEnv *)->GetStringLength(jstring _jstr);
C、将jstring对象 拷贝到 const jchar*指针字符串
C.1、拷贝Java字符串并以UTF-8编码传入jstr
(JNIEnv *)->GetStringRegion(jstring _jstr, jsize start, jsize len, jchar* _pjchar);
C.2、拷贝Java字符串并以UTF-16编码传入jstr
(JNIEnv *)->GetStringUTFRegion(jstring _jstr, jsize start, jsize len, char* _pchar);
参数 : _jstr是一个jstring对象,start是拷贝字符串的开始位置,len是拷贝字符串的长度,jstr是目标指针字符串
(1)、在Java1.2出来的函数,这个函数的动作是把Java字符串的内容直接拷贝到C/C++的字符串数组中,在呼叫这个函数之前必须有一个C/C++分配出来的字符串(具体看下面的例子),然后传入到这个函数中进行字符串的拷贝
(2)、由于C/C++中分配内存开销相对小,而且Java中的String内容拷贝的开销可以忽略,更好的一点是此函数不分配内存,不会抛出OutOfMemoryError异常
(3)、ZC: 上面出现的"这个函数"、"此函数"应该值得就是 GetStringRegion 和 GetStringUTFRegion
D、将jstring对象转化成const jchar*字符串指针
D.1、const jchar* (JNIEnv *)->GetStringChars(jstring _jstr, jboolean* copied);
返回一个UTF-16编码的宽字符串(jchar*)
参数:
_jstr 是字符串对象
copied是指传入的是一个jboolean指针,用来标识是否对Java的String对象进行了拷贝的,如果传入的这个jboolean指针不是NULL,则它会给该指针所指向的内存传入JNI_TRUE或JNI_FALSE标识是否进行了拷贝,传入NULL表示不关心是否拷贝字符串,它就不会给jboolean* 指向的内存赋值
其对应的释放内存指针的方法:
(JNIEnv *)->ReleaseStringChars(jstring _jstr, const jchar* _pjchar);
参数:
_jstr 是jstring对象,
_pjchar是字符串指针
D.2、const char* (JNIEnv *)->GetStringUTFChars(jstring _jstr , jboolean* copied)
这个方法是可以取得UTF-8编码的字符串(char*)
参数的含义和GetStringChars方法是一样的
这个方法也有对应的一个释放内存的方法:
(JNIEnv *)->ReleaseStringUTFChars(jstring _jstr , const char* _pchar);
参数的含义和上面的ReleaseStringChars方法的参数的含义是一样的
需要注意的是:
“(来自 http://www.360doc.cn/article/14233282_321497569.html)
当从JNI函数GetStringChars中返回得到字符串B时,如果B是原始字符串java.lang.String的拷贝,则isCopy被赋值为JNI_TRUE。如果B和原始字符串指向的是JVM中的同一份数据,则isCopy被赋值为JNI_FALSE。当isCopy值为JNI_FALSE时,本地代码决不能修改字符串的内容,否则JVM中的原始字符串也会被修改,这会打破JAVA语言中字符串不可变的规则。
通常,因为你不必关心JVM是否会返回原始字符串的拷贝,你只需要为isCopy传递NULL作为参数。
JVM是否会通过拷贝原始Unicode字符串来生成UTF-8字符串是不可以预测的,程序员最好假设它会进行拷贝,而这个操作是花费时间和内存的。一个典型的JVM会在heap上为对象分配内存。一旦一个JAVA字符串对象的指针被传递给本地代码,GC就不会再碰这个字符串。换言之,这种情况下,JVM必须pin这个对象。可是,大量地pin一个对象是会产生内存碎片的,因为,虚拟机会随意性地来选择是复制还是直接传递指针。
当你不再使用一个从GetStringChars得到的字符串时,不管JVM内部是采用复制还是直接传递指针的方式,都不要忘记调用ReleaseStringChars。根据方法GetStringChars是复制还是直接返回指针,ReleaseStringChars会释放复制对象时所占的内存,或者unpin这个对象。
” ZC: 这里的 JVM的pin操作,没有查到具体的解释...
E、将jstring对象转化成const jchar*字符串指针 (ZC: 带 临界区 操作[互斥/死锁])
const jchar* (JNIEnv *)->GetStringCritical(jstring _jstr, jboolean* copied);
参数:
_jstr 是字符串对象,
copied 上面的方法已经做了解释了,这里就不多说了
这个方法的作用是为了增加直接传回指向Java字符串的指针的可能性(而不是拷贝),JDK1.2出来了新的函数GetStringCritical/ReleaseStringCritical,在GetStringCritical/ReleaseStringCritical之间是一个关键区,在这个关键区域之间不能呼叫JNI的其他函数和会造成当前线程中断,或是会让当前线程等待的任何本地代码,否则将造成关键区代码执行期间垃圾回收器停止运作,任何触发垃圾回收器的线程也会暂停,其他的触发垃圾回收器的线程不能前进直到当前线程结束而激活垃圾回收器
在关键区域中千万不要出现中断操作,或是在JVM中分配任何新对象,否则会造成JVM死锁
虽说这个函数会增加直接传回指向Java字符串的指针的可能性,不过还是会根据情况传回拷贝过的字符串 (ZC: 好蛋疼...)
不支持GetStringUTFCritical,没有这样的函数,由于Java字符串用的是UTF-16,要转成UTF-8编码的字符串始终需要进行一次拷贝,所以没有这样的函数
这个方法和第四个方法(ZC: GetStringChars)是一样的功能
其对应的释放内存指针的方法:
(JNIEnv *)->ReleaseStringCritical(jstring _jstr, const jchar* _pjchar);
1、
2、
3、
4、
5、
JNI_Z_09_Java的字符串的更多相关文章
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率
之前一篇里写过字符串常用类的三种方式<java中的字符串相关知识整理>,只不过这个只是分析并不知道他们之间会有多大的区别,或者所谓的StringBuffer能提升多少拼接效率呢?为此写个简 ...
- java中的字符串相关知识整理
字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...
- JavaScript 字符串实用常操纪要
JavaScript 字符串用于存储和处理文本.因此在编写 JS 代码之时她总如影随形,在你处理用户的输入数据的时候,在读取或设置 DOM 对象的属性时,在操作 Cookie 时,在转换各种不同 Da ...
- Java 字符串格式化详解
Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...
- Redis的简单动态字符串实现
Redis 没有直接使用 C 语言传统的字符串表示(以空字符结尾的字符数组,以下简称 C 字符串), 而是自己构建了一种名为简单动态字符串(simple dynamic string,sds)的抽象类 ...
- ASP.NET加密和解密数据库连接字符串
大家知道,在应用程序中进行数据库操作需要连接字符串,而如果没有连接字符串,我们就无法在应用程序中完成检索数据,创建数据等一系列的数据库操作.当有人想要获取你程序中的数据库信息,他首先看到的可能会是We ...
- Javascript正则对象方法与字符串正则方法总结
正则对象 var reg = new Regexp('abc','gi') var reg = /abc/ig 正则方法 test方法(测试某个字符串是否匹配) var str = 'abc123'; ...
- 微信小程序中利用时间选择器和js无计算实现定时器(将字符串或秒数转换成倒计时)
转载注明出处 改成了一个单独的js文件,并修改代码增加了通用性,点击这里查看 今天写小程序,有一个需求就是用户选择时间,然后我这边就要开始倒计时. 因为小程序的限制,所以直接选用时间选择器作为选择定时 ...
随机推荐
- 160725、Java Map按键排序和按值排序
按键排序(sort by key) jdk内置的Java.util包下的TreeMap<K,V>既可满足此类需求,原理很简单,其重载的构造器之一 有一个参数,该参数接受一个比较器,比较器定 ...
- mysql 中事件
# 创建存储过程 /* delimiter // create procedure test() begin update test SET name = date_format(now(),'%Y- ...
- mfc 对话框程序 托盘实现
1 在头文件里面定义 消息 #define WM_SHOWTASK WM_USER+10 在主窗口类里面定义 一个变量 两个函数 a 变量 托盘结构体的变量 NOTIFYICONDATA m_nid; ...
- z waiting to receive.**B0100000023be50
[root@b ~]# rz▒z waiting to receive.**B0100000023be50
- openssl update--centos 6.5
cd /usr/local/src #wget http://www.openssl.org/source/openssl-1.0.1h.tar.gz #tar -zxvf openssl-1.0.1 ...
- awesome-modern-cpp
Awesome Modern C++ A collection of resources on modern C++. The goal is to collect a list of resouce ...
- (转)java类到底是如何加载并初始化的?
Java虚拟机如何把编译好的.class文件加载到虚拟机里面?加载之后如何初始化类?静态类变量和实例类变量的初始化过程是否相同,分别是如何初始化的呢?这篇文章就 是解决上面3个问题的. 若有不正之处, ...
- hexo+yilia主题博客如何添加图标icon
1. 先去比特虫网站做icon图标 2. 图片放到hexo/source/img文件夹下 3. 找到hexo\themes\modernist\layout_partial\head.ejs,设置为 ...
- 0601-Zuul构建API Gateway-API gateway简介、基础使用、路由配置、负载配置
一.API Gateway简介 参看:http://www.cnblogs.com/bjlhx/p/8794437.html 二.zuul简介[路由器和过滤器:Zuul] 在微服务架构的组成部分进行路 ...
- Linux学习笔记之文件权限
前言: 说起文件权限,大家在windows下应该很熟悉就对文件右键属性,然后配置一点什么读写之类的权限,然后可以分配到每个的人. 对于linux 我先为大家介绍一个使用者和组和其他的概念说明一下 文件 ...