将 std::string 转换为 ndk jstring。

问题描述 投票:5回答:1

我正试图为现有的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个回答
0
投票

如果你的字符串(无论是c-style字符串还是std::string或std::wstring)的第一个字符包含一个0,这意味着它是空结束的,并且该字符串的内容是一个空字符串。

需要注意的是,我们用于字符串的容器,依赖于最后一个元素的事实,终止字符串的元素将是零。

如果我们手动地把以零结束的空元素改成另一个值(可打印与否并不重要),我们的代码将面临很多危险。如果一个简单的strlen被调用到一个非空结束的字符串上,它将读取连续的内存,直到它找到一个零(但它将不再代表字符串的长度)。考虑到这种情况,你可以想象,违反这个规则很可能会影响应用程序的其他部分。

这一点的共鸣有点残酷,但很直接,看一看 在这种情况下:

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

所以 *end 只有遇到0时才会停止,但由于我们假设它将被删除,所以我们最终会读取内存的其他部分,这样就犯了一个明显的长度计算错误。

回到你的案例

为什么在你的情况下会发生这种情况,原因是:在字符串的第一个位置插入了一个零的bug,或者字符串ir只是空的,或者--更有趣的是--你在某个地方传递了一个字符串,你返回了一个新的空字符串,而不是你想要的字符串。

这个问题和UTF8几乎没有关系,因为使用UTF8时,你可能会遇到的是,字形的字符串长度,比存储字符串本身所需的字节数要短。

当使用UTF8时,你需要意识到字节数等于字形数的假设(在ASCII中有效),已经不再有效,因为要打印0-127范围内的东西,你可能需要额外的字节。

那么你所显示的情况就不是UTF的责任了。

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


0
投票

创建一个预期长度的字节数组,并在数组中加入以下内容 拷贝 你的std::string到这个数组。现在,你可以 转化 byte[] 到字符串 提供适当的字符集给 字符串() 构造者。

© www.soinside.com 2019 - 2024. All rights reserved.