经过很长时间才找到解决方案。我找到了一条路:
在 java 中,unicode char 将使用 2 个字节 (utf16) 进行编码。所以jstring 将包含字符utf16。 c++ 中的std::string 本质上是一个字节串,而不是字符,所以如果我们想将jstring 从JNI 传递到c++,我们需要将utf16 转换为字节。
在文档JNI functions中,我们有两个函数可以从jstring中获取字符串:
// Returns a pointer to the array of Unicode characters of the string.
// This pointer is valid until ReleaseStringchars() is called.
const jchar * GetStringChars(JNIEnv *env, jstring string, jboolean *isCopy);
// Returns a pointer to an array of bytes representing the string
// in modified UTF-8 encoding. This array is valid until it is released
// by ReleaseStringUTFChars().
const char * GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy);
GetStringUTFChars,它会返回一个modified utf8。
GetStringChars 将返回 jbyte *,我们将从 jbytes 中读取 char 代码并在 c++ 中将其转换为 char
这是我的解决方案(适用于 ascii 和 utf8 字符):
std::string jstring2string(JNIEnv *env, jstring jStr) {
if (!jStr)
return "";
const jclass stringClass = env->GetObjectClass(jStr);
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(jStr, getBytes, env->NewStringUTF("UTF-8"));
size_t length = (size_t) env->GetArrayLength(stringJbytes);
jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
std::string ret = std::string((char *)pBytes, length);
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
env->DeleteLocalRef(stringJbytes);
env->DeleteLocalRef(stringClass);
return ret;
}