Java本机代码字符串结束

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中使用的内部两字节字符串表示,虽然发现证明留给读者作为练习留给读者.)

  • **哇**.为搜索努力+1 ...我实际上已经陷入了阅读:你是文件奥秘的柯南道尔;-)(说真的,一个非常好的工作). (2认同)

cez*_*tko 7

当前对该问题的所有答案似乎都已过时(Edward Thomson 的答案上次更新可以追溯到 2015 年),或者参考 Android JNI 文档,该文档仅在 Android 世界中具有权威性。此事已在最近(2017 年)官方 Oracle JNI 文档清理和更新中得到澄清,更具体地说是在本期

现在JNI规范明确指出:

字符串操作

本规范没有对 JVM 如何在内部表示 Java 字符串做出任何假设。从这些操作返回的字符串:

  • 获取字符串字符()
  • 获取字符串UTFChars()
  • 获取字符串区域()
  • 获取字符串UTFRegion()
  • 获取字符串关键()

因此不需要以 NULL 结尾。程序员应通过 GetStringLength() 或 GetStringUTFLength() 确定缓冲区容量要求。

在一般情况下,这意味着永远不应该假设 JNI 返回的字符串以 null 结尾,甚至是 UTF-8 字符串。在务实的世界中,人们可以在受支持的 JVM 列表中测试特定行为。根据我的经验,参考我实际测试过的 JVM:

  • Oracle JVM 会以 null 终止 UTF-16(使用\u0000)和 UTF-8 字符串(使用'\0');
  • Android JVM 会终止 UTF-8 字符串,但不会终止 UTF-16 字符串。