Goo*_*ozo 14 java-native-interface
字符串是否GetStringUTFChars()以空终止字符从末尾返回?或者我需要确定使用的长度GetStringUTFLength并自己终止它吗?
Edw*_*son 24
是的,GetStringUTFChars返回以null结尾的字符串.但是,我认为你不应该接受我的话,相反,你应该找到一个回答这个问题的权威在线资源.
让我们从实际的Java Native Interface Specification本身开始,它说:
返回指向字节数组的指针,该字节数组表示修改后的UTF-8编码中的字符串.此数组在释放之前有效
ReleaseStringUTFChars().
哦,令人惊讶的是它并没有说它是否为空终止.男孩,这似乎是一个巨大的疏忽,幸运的是有人在2008年就在Sun的Java bug数据库上记录了这个bug.关于bug的注释指出了一个类似但不同的文档错误(没有动作就关闭了),这表明读者购买了一本书" Java本地接口:程序员指南和规范 ",因为有人建议这成为JNI的新规范.
但是,我们正在寻找一个权威的在线资源,这既不是权威的(这不是还没有规范),也不在线.
幸运的是,对某个受欢迎的在线图书零售商的书的评论表明,这本书可以从Sun在线免费获得,这至少可以满足在线部分.Sun的JNI网页有一个看起来非常接近的链接,但是这个链接很遗憾地没有它所说的去的地方.
所以我担心我不能指出你这是一个权威的在线资源,你将不得不购买这本书(它实际上是一本好书),它将向你解释:
UTF-8字符串始终以
'\0'字符结尾,而Unicode字符串则不是.为了找出以jstringUTF-8格式表示a需要多少字节,JNI程序员可以strlen在结果上调用ANSI C函数GetStringUTFChars,或者直接调用引用GetStringUTFLength上的JNI函数jstring.
(注意,在上面的句子"的Unicode"是指"UTF-16",或更准确地"通过Java中使用的内部两字节字符串表示,虽然发现证明其留给读者作为练习留给读者.)
当前对该问题的所有答案似乎都已过时(Edward Thomson 的答案上次更新可以追溯到 2015 年),或者参考 Android JNI 文档,该文档仅在 Android 世界中具有权威性。此事已在最近(2017 年)官方 Oracle JNI 文档清理和更新中得到澄清,更具体地说是在本期中。
现在JNI规范明确指出:
字符串操作
本规范没有对 JVM 如何在内部表示 Java 字符串做出任何假设。从这些操作返回的字符串:
- 获取字符串字符()
- 获取字符串UTFChars()
- 获取字符串区域()
- 获取字符串UTFRegion()
- 获取字符串关键()
因此不需要以 NULL 结尾。程序员应通过 GetStringLength() 或 GetStringUTFLength() 确定缓冲区容量要求。
在一般情况下,这意味着永远不应该假设 JNI 返回的字符串以 null 结尾,甚至是 UTF-8 字符串。在务实的世界中,人们可以在受支持的 JVM 列表中测试特定行为。根据我的经验,参考我实际测试过的 JVM:
\u0000)和 UTF-8 字符串(使用'\0');