将std::string转换为ndk-jstring

Convert std::string to ndk jstring

本文关键字:ndk-jstring 转换 string std      更新时间:2023-10-16

我正在尝试为现有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,并将字符串的长度作为参数?

创建一个预期长度的字节数组,并将std::string复制到此数组。现在,您可以将byte[]转换为String,为String()构造函数提供适当的字符集。

如果您的字符串(如果它是c样式字符串、std::字符串或std::wstring)的第一个字符包含零,则表示它以null结尾,并且该字符串的内容是空字符串。

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

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

原因有点残酷,但很直接;看看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++端为空的原因。