如何正确将含西里尔字母的C++字符串转换为JNI jstring?
解决JNI中俄语字符串转jstring乱码问题
你的问题核心是编码不匹配:JNI的NewStringUTF要求输入的const char*必须是UTF-8编码,但你直接写的"привет"字符串编码取决于源文件保存格式和编译器设置(比如Windows下默认可能是Windows-1251),非UTF-8的字节流被当作UTF-8解析,就会出现你看到的乱码。
解决方案1:直接使用UTF-8编码的字符串(推荐)
如果是代码中直接写俄语字符串,按以下步骤操作:
- 将源文件保存为UTF-8编码(现代编译器普遍兼容带/不带BOM的UTF-8)
- 使用C++11及以上标准的
u8前缀,强制编译器生成UTF-8编码的char数组:
const char* msg = u8"привет"; return env->NewStringUTF(msg);
解决方案2:从其他编码转换为UTF-8
如果字符串来自其他编码来源(比如旧系统的Windows-1251编码),需要先转成UTF-8再调用NewStringUTF。以下是Windows平台的示例:
#include <windows.h> jstring convertWin1251ToJstring(JNIEnv* env, const char* win1251Str) { // 第一步:Windows-1251转UTF-16宽字符 int wideLen = MultiByteToWideChar(1251, 0, win1251Str, -1, nullptr, 0); wchar_t* wideStr = new wchar_t[wideLen]; MultiByteToWideChar(1251, 0, win1251Str, -1, wideStr, wideLen); // 第二步:UTF-16转UTF-8 int utf8Len = WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, nullptr, 0, nullptr, nullptr); char* utf8Str = new char[utf8Len]; WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, utf8Str, utf8Len, nullptr, nullptr); // 生成jstring jstring result = env->NewStringUTF(utf8Str); // 释放内存 delete[] wideStr; delete[] utf8Str; return result; } // 使用示例 // return convertWin1251ToJstring(env, "привет");
跨平台场景可使用iconv或ICU库完成编码转换,逻辑一致:先转成中间编码(如UTF-16),再转成UTF-8。
解决方案3:直接用宽字符转jstring
如果你的C++字符串是UTF-16编码的宽字符(Windows下wchar_t为16位,匹配JNI的jchar类型),可直接调用NewString:
const wchar_t* msg = L"привет"; // 注意:Linux下wchar_t是32位,需先转成16位UTF-16才能使用此方法 return env->NewString(reinterpret_cast<const jchar*>(msg), wcslen(msg));
此方法仅Windows下通用,跨平台需额外处理,不如UTF-8方案灵活。
内容的提问来源于stack exchange,提问作者nonxis
相关产品推荐
相关产品推荐

