java C++ std::string to jstring 固定长度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27303316/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 11:35:09  来源:igfitidea点击:

C++ std::string to jstring with a fixed length

javac++stringjava-native-interface

提问by Eli Rising

I'm trying to turn a C++ std::string into a jstring and return it. This would be easy enough with

我正在尝试将 C++ std::string 转换为 jstring 并返回它。这很容易

JNIEnv*->NewStringUTF(stdString.c_str())

but the problem is that the string I'm converting has almost randomly interspersed null characters in it. This is a problem for the c_str(), but not the std::string. NewStringUTFwill only catch a portion of the full std::string. There is some hope in that the std::stringhas a length()function, which gets the full length, ignoring the problematic char* \0characters.

但问题是我正在转换的字符串中几乎随机散布着空字符。这是 的问题c_str(),但不是std::stringNewStringUTF只会捕获完整的一部分std::string。有一些希望std::string有一个length()函数,它获得全长,忽略有问题的 char*\0字符。

There's a separate function NewStringthat takes in a jchar* and a jsize*, so that looks promising, but I can't get the std::string converted properly to the jchar*. I tried making it a byte array, but I probably wasn't doing it right. I had further problems converting the int given by the length()into a jsize, which was required by the NewString call.

有一个单独的函数NewString接受 jchar* 和 jsize*,所以看起来很有希望,但我无法将 std::string 正确转换为 jchar*。我试着把它变成一个字节数组,但我可能做得不对。我在将 给出的 int 转换length()为 NewString 调用所需的 jsize 时遇到了进一步的问题。

I have done a bit of work with vector<char> byteArray(stdString.begin(), stdString.end()), but that didn't get me very far, probably because that is messing up what the original string is.

我已经用 做了一些工作vector<char> byteArray(stdString.begin(), stdString.end()),但这并没有让我走得很远,可能是因为这弄乱了原始字符串的内容。

Here is the basic starter function I have, which worked with strings without null chars:

这是我拥有的基本启动函数,它处理没有空字符的字符串:

jstring StringToJString(JNIEnv * env, const std::string & nativeString) {
    return env->NewStringUTF(nativeString.c_str());
}

As a side note, this function is being used inside a JNI wrapper file for returning an object's std::string.

作为旁注,此函数在 JNI 包装器文件中使用,用于返回对象的std::string.

Thanks for any help or information sources!

感谢任何帮助或信息来源!

回答by Eli Rising

I made my own workaround solution taking RedAlert's advice.

我根据 RedAlert 的建议制定了自己的解决方案。

Java now expects a byte[] from the native call:

Java 现在需要来自本机调用的 byte[]:

private native byte[] toString(long thiz);

The toString method now calls this method inside it on a std::string:

toString 方法现在在其内部调用此方法std::string

jbyteArray StringToJByteArray(JNIEnv * env, const std::string &nativeString) {
    jbyteArray arr = env->NewByteArray(nativeString.length());
    env->SetByteArrayRegion(arr,0,nativeString.length(),(jbyte*)nativeString.c_str());
    return arr;
}

And the java level receives the data like this:

而java级别接收数据是这样的:

byte[] byteArray = toString(mNativeInstance);
String nativeString = "";
try {
    nativeString = new String(byteArray, "UTF-8");
} catch (UnsupportedEncodingException e) {
    Log.e(TAG, "Couldn't convert the jbyteArray to UTF-8");
    e.printStackTrace();
}