JNI字符串和C字符串
JNI strings and C strings
在JNI函数的文档中FindClass我可以阅读关于参数名称的信息:
name:完全限定的类名(…)字符串以修改后的UTF-8编码。
根据修改后的文档,UTF-8必须以双"\0"字符结尾:
空字符(char)0使用两字节格式而不是一字节格式进行编码
这是否意味着我应该以这种方式从C调用FindClass:FindClass("java/lang/String ")
即结尾有双"\0"?
字符集、编码和终止是三件不同的事情。显然,编码是为特定的字符集设计的,但字符集可以用多种方式编码。通常,终止符(如果使用的话)是一个编码字符,但对于修改后的UTF-8,情况并非如此。
Java使用Unicode字符集。对于字符串和字符类型,它使用UTF-16编码。对字符串类型进行计数;它不使用终止符。
在C语言中,终止字符串是常见的,各种字符集的单字节编码也是常见的。C和C++编译器使用NUL字符终止文字字符串。在编译器的目标字符集编码中,这是一个或两个0x00字节。对于非控制ASCII字符,几乎所有常见的字符集及其编码都有相同的字节表示。Unicode字符集的UTF-8编码也是如此。(但是,请注意,对于有限子集之外的字符,情况并非如此。)
JNI设计者选择在C字符串之间使用这种有限的"互操作性"。许多JNI函数接受0x00终止的修改的UTF-8字符串。这些与C编译器从源代码中的文字字符串生成的内容兼容,同样前提是字符限制为非控制ASCII字符。这涵盖了编写Java包&JNI中的类、方法和字段字符串。(好吧,差不多:Java允许在标识符中使用任何Unicode货币符号。)
因此,您可以以所见即所得的样式将C字符串文本传递给JNI函数。不需要添加终止符——编译器会这样做C编译器会将额外的"\0"字符编码为0x00,所以它不会造成任何危害,但不是必需的。
对标准UTF-8编码进行了一些修改。一种是允许C函数使用0x00终止符来"处理"修改后的UTF-8字符串,对NUL字符(U+000000)进行编码以避免0x00,这将是标准。这允许将修改后的UTF-8字符串放入缓冲区,在原始编码字符串的字节之外使用0x00终止符。另一个修改有点深奥,但这两个修改都使修改后的UTF-8字符串与严格兼容的UTF-8函数不兼容。
您没有问,但在JNI中还有另一种使用0x00终止的、经过修改的UTF-8字符串的方法。它具有GetStringUTFChars
和NewStringUTF
功能。(JNI文档实际上并没有说GetStringUTFChars
返回0x00终止的字符串,但没有已知的JVM实现没有。请查看JVM实现者的文档或源代码。)这些函数是基于相同的"互操作性"设计的。但是,用例不同,这使得它们很危险它们通常用于在C函数之间传递Java字符串。一般来说,C函数不知道什么是经过修改的UTF-8,甚至可能不知道UTF-8或Unicode是什么。使用Java String
和Charset
类来转换C函数所设计的字符集和编码更为直接。通常,是系统设置、用户设置、应用程序设置或线程设置决定了C函数正在使用哪个。Java String
类在没有为转换指定特定编码时,会尝试遵守这些设置。但是,在许多情况下,所需的编码是固定的,并且可以明确指定。
不,您没有编码终止零,它不是类名的一部分。
不,根据我发现的第一个引用,这意味着它应该像这样编码:
FindChar("java/lang/Stringxc0x80");
^
|
|
This is not the shortest
way to encode the codepoint
U+0000, which is why it's
"modified" UTF-8.
请注意,这假设您确实在寻找名称以U+0000结尾的类名,这是不太可能的。C字符串应该像正常情况一样终止,只使用一个0字节,就像您从中得到的那样
FindChar("java/lang/String");
Modified UTF-8提供的U+0000的特殊2字节编码只在您想将U+0000放入字符串中,并且仍然能够将其与C终止符区分开来时才重要。
- 如何通过 JNI 将 C 字符串表情符号传递给 Java
- React Native (Android):无法通过 JNI 在 jobject 中返回字符串
- 如何将字符串数组返回到 java JNI
- 如何从 C/C++ 在 JNI for Java 中创建 UTF16 字符串?
- JNI、C++在堆栈中推送字符串
- 如何将两个 jlong 数据类型转换为 jstring,然后将两个字符串连接在一起以便从 JNI 将字符串返回给 jav
- 使用 JNI 从 Android 应用程序向C++发送字符串
- 如何将字符串数组从C++返回到Java(JNI)
- JNI - 如何填充从 C++ 传递到 Java 的字符串
- JNI将字符串从Java传递到C ,然后将C 字符串传递给字符串数组
- JNI 代码返回字符串,但得到错误 java.lang.UnsatisfiedLinkError: com.packag
- 如何使用 2 个字符串参数从 jni java 库调用
- 通过在 qt 中从 c++ JNI 发送字符串来显示 Android 中的 Toast
- 在JNI呼叫中使用后,应删除/释放JarrayObject(字符串阵列)
- 调用静态 JNI 方法以从C++返回字符串
- 使用java jni时转换字符串类型
- 静态 c++ 对象中的 JNI 环境指针并调用连续两次使用字符串参数的 Java 函数会使 JVM 崩溃
- 从 Java 获取字符串数组以C++ JNI
- JNI:将Java字符串转换为代码页1252
- 在android NDK jni中加密和解密utf8字符串