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

如何在不使用iconv的情况下将C++的std::wstring转换为jstring?

不用iconv把C++的std::wstring转成jstring的方法

没问题!我来给你梳理下不用iconv实现这个转换的方案,其实可以借助JNI自带的方法和C++标准库来搞定,分平台说更清楚:

第一种情况:Windows平台

在Windows上,std::wstring底层的wchar_t是16位的,刚好和JNI里jchar(无符号16位整数)的UTF-16编码匹配,所以直接用JNI的NewString方法就行,完全不需要额外转换:

#include <jni.h>
#include <string>

jstring wstring_to_jstring(JNIEnv* env, const std::wstring& wstr) {
    if (wstr.empty()) {
        return env->NewStringUTF("");
    }
    // Windows下wchar_t和jchar编码兼容,直接强转就行
    return env->NewString(reinterpret_cast<const jchar*>(wstr.c_str()), static_cast<jsize>(wstr.size()));
}

第二种情况:Linux/macOS平台

类Unix系统里,std::wstring的wchar_t是32位的(对应UTF-32编码),而JNI的jchar是UTF-16格式,这时候需要把UTF-32转成UTF-16。不用iconv的话,C++11及以上的标准库自带的std::wstring_convert和std::codecvt就能搞定:

#include <jni.h>
#include <string>
#include <locale>
#include <codecvt>

jstring wstring_to_jstring(JNIEnv* env, const std::wstring& wstr) {
    if (wstr.empty()) {
        return env->NewStringUTF("");
    }

    // 把UTF-32的std::wstring转成UTF-16的std::u16string
    std::wstring_convert<std::codecvt_utf16<char32_t>, char32_t> converter;
    std::u16string u16str;
    try {
        u16str = converter.to_bytes(reinterpret_cast<const char32_t*>(wstr.c_str()),
                                    reinterpret_cast<const char32_t*>(wstr.c_str() + wstr.size()));
    } catch (const std::range_error& e) {
        // 转换出错的话,给Java层抛个异常提示
        env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), "Invalid UTF-32 string");
        return nullptr;
    }

    // 用转换后的UTF-16字符串创建jstring
    return env->NewString(reinterpret_cast<const jchar*>(u16str.c_str()), static_cast<jsize>(u16str.size()));
}

跨平台兼容写法

如果你的代码要跑在多个平台上,可以用预编译宏区分不同系统:

#include <jni.h>
#include <string>

#ifdef _WIN32
jstring wstring_to_jstring(JNIEnv* env, const std::wstring& wstr) {
    if (wstr.empty()) {
        return env->NewStringUTF("");
    }
    return env->NewString(reinterpret_cast<const jchar*>(wstr.c_str()), static_cast<jsize>(wstr.size()));
}
#else
#include <locale>
#include <codecvt>
jstring wstring_to_jstring(JNIEnv* env, const std::wstring& wstr) {
    if (wstr.empty()) {
        return env->NewStringUTF("");
    }

    std::wstring_convert<std::codecvt_utf16<char32_t>, char32_t> converter;
    std::u16string u16str;
    try {
        u16str = converter.to_bytes(reinterpret_cast<const char32_t*>(wstr.c_str()),
                                    reinterpret_cast<const char32_t*>(wstr.c_str() + wstr.size()));
    } catch (const std::range_error& e) {
        env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), "Failed to convert UTF-32 to UTF-16");
        return nullptr;
    }

    return env->NewString(reinterpret_cast<const jchar*>(u16str.c_str()), static_cast<jsize>(u16str.size()));
}
#endif

几个要注意的点

  • 得确保你的std::wstring是对应平台的标准编码(Windows是UTF-16,类Unix是UTF-32),如果是其他编码(比如Windows上的GBK宽字符),那还是得先转成对应平台的标准编码才能用这些方法。
  • std::wstring_convert在C17里被标记为废弃了,但大部分编译器还是支持的,如果要兼容C17及以后,可以找替代的编码转换实现,不过日常用这个完全够。
  • 转换过程中记得处理异常,不然容易崩,还可以给Java层抛异常让上层处理问题。

内容的提问来源于stack exchange,提问作者user4122560

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:32:35