You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确将含西里尔字母的C++字符串转换为JNI jstring?

解决JNI中俄语字符串转jstring乱码问题

你的问题核心是编码不匹配:JNI的NewStringUTF要求输入的const char*必须是UTF-8编码,但你直接写的"привет"字符串编码取决于源文件保存格式和编译器设置(比如Windows下默认可能是Windows-1251),非UTF-8的字节流被当作UTF-8解析,就会出现你看到的乱码。

解决方案1:直接使用UTF-8编码的字符串(推荐)

如果是代码中直接写俄语字符串,按以下步骤操作:

  1. 将源文件保存为UTF-8编码(现代编译器普遍兼容带/不带BOM的UTF-8)
  2. 使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 11:35:17