【问题标题】:Convert std::string to ndk jstring将 std::string 转换为 ndk jstring
【发布时间】:2015-07-12 09:31:18
【问题描述】:

我正在尝试为现有 C++ 代码创建 Java 接口。 我的一项功能与此类似:

JNIEXPORT jstring JNICALL Java_com_testproxy_NativeInterface_serialize
    (JNIEnv* env, jobject obj, along op)
{
     return env -> NewStringUTF(<somestdstring>.c_str());
}

问题在于,在某些情况下,第一个元素是'\0',因此,返回值是一个空字符串。那么是否有一些函数可以将 char* 转换为 jstring,它也将字符串的长度作为参数?

【问题讨论】:

标签: java android c++ android-ndk


【解决方案1】:

如果您的字符串(无论是 c 风格的字符串还是 std:: 字符串或 std::wstring)的第一个字符都包含零,这意味着它是以空值结尾的,并且该字符串的内容string 是一个空字符串。

意识到我们用于字符串的容器非常重要,依赖于最后一个元素,终止字符串将为零。

如果我们手动设法将终止零的 null 更改为另一个值(可打印与否无关紧要),我们将在代码中暴露出很多危险。如果在非空终止字符串上调用简单的 strlen,它将读取连续内存,直到找到零(但它不再代表字符串的长度)。鉴于这种情况,您可以想象违反该规则很可能会危及应用程序的其余部分。

这样做的原因有点残酷,但直截了当;看at this implementation of strlen

std::size_t strlen(const char* start) {
   const char* end = start;
   while(*end++ != 0);
   return end - start - 1;
}

所以*end 只会在遇到零时停止,但由于我们假设它会被删除,我们最终会读取内存的其他部分,从而在长度计算中犯下一个明显的错误。

回到你的案例

在您的情况下可能发生这种情况的原因是在字符串的第一个位置插入零的错误,或者字符串只是空的,或者 - 更有趣的是 - 您在某处传递了一个字符串,然后您返回一个新的空字符串,而不是您想要的字符串。

这件事与 UTF8 几乎没有关系,就像 UTF8 一样,您可能会遇到字形中字符串的长度小于存储字符串本身所需的字节数。

使用 UTF8 时,您需要注意字节数等于字形数(在 ASCII 中有效)的假设不再有效,因为要打印超出 0-127 范围的内容,您可能需要额外的字节。

您展示的情况不是 UTF 的责任。

我建议首先调查这些字符串在 C++ 端为空的原因。

【讨论】:

    【解决方案2】:

    创建一个预期长度的字节数组,并将 copy 你的 std::string 放到这个数组中。现在,您可以convert the byte[] to StringString() 构造函数提供适当的字符集。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-28
      • 2012-05-16
      • 1970-01-01
      相关资源
      最近更新 更多