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

如何将Win32 <tchar.h>中的TCHAR字符串转换为UTF-8字符串?

无需依赖区域设置的TCHAR转UTF-8方案

由于TCHAR的实际类型由项目的UNICODE/_MBCS宏决定,我们可以直接调用Windows原生API完成转换,全程不依赖区域设置,完美适配DLL场景:

核心思路

Windows API提供的WideCharToMultiByte和MultiByteToWideChar函数,通过指定编码页CP_UTF8,可以精准控制转换目标为UTF-8,完全避开区域设置的影响。

情况1:UNICODE模式(TCHAR = wchar_t)

直接将宽字符转换为UTF-8多字节字符串:

#include <windows.h>
#include <tchar.h>
#include <stdlib.h>

char* TCHARToUTF8(const TCHAR* tstr)
{
    if (!tstr) return NULL;

    // 获取所需UTF-8缓冲区大小
    int utf8Len = WideCharToMultiByte(CP_UTF8, 0, tstr, -1, NULL, 0, NULL, NULL);
    if (utf8Len == 0) return NULL;

    // 分配内存(调用者需用free()释放)
    char* utf8Str = (char*)malloc(utf8Len * sizeof(char));
    if (!utf8Str) return NULL;

    // 执行转换
    WideCharToMultiByte(CP_UTF8, 0, tstr, -1, utf8Str, utf8Len, NULL, NULL);
    return utf8Str;
}

情况2:ANSI模式(TCHAR = char)

先将ANSI编码的TCHAR转换为宽字符,再转成UTF-8:

#include <windows.h>
#include <tchar.h>
#include <stdlib.h>

char* TCHARToUTF8(const TCHAR* tstr)
{
    if (!tstr) return NULL;

    // 获取宽字符缓冲区大小
    int wideLen = MultiByteToWideChar(CP_ACP, 0, tstr, -1, NULL, 0);
    if (wideLen == 0) return NULL;

    wchar_t* wideStr = (wchar_t*)malloc(wideLen * sizeof(wchar_t));
    if (!wideStr) return NULL;

    // ANSI转宽字符
    MultiByteToWideChar(CP_ACP, 0, tstr, -1, wideStr, wideLen);

    // 宽字符转UTF-8
    int utf8Len = WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, NULL, 0, NULL, NULL);
    if (utf8Len == 0) {
        free(wideStr);
        return NULL;
    }

    char* utf8Str = (char*)malloc(utf8Len * sizeof(char));
    if (!utf8Str) {
        free(wideStr);
        return NULL;
    }

    WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, utf8Str, utf8Len, NULL, NULL);
    free(wideStr);
    return utf8Str;
}

通用兼容版本(自动适配宏定义)

通过预编译宏合并两种情况,适配不同项目设置:

#include <windows.h>
#include <tchar.h>
#include <stdlib.h>

char* TCHARToUTF8(const TCHAR* tstr)
{
    if (!tstr) return NULL;

#ifdef UNICODE
    int utf8Len = WideCharToMultiByte(CP_UTF8, 0, tstr, -1, NULL, 0, NULL, NULL);
    if (utf8Len == 0) return NULL;

    char* utf8Str = (char*)malloc(utf8Len * sizeof(char));
    if (!utf8Str) return NULL;

    WideCharToMultiByte(CP_UTF8, 0, tstr, -1, utf8Str, utf8Len, NULL, NULL);
    return utf8Str;
#else
    int wideLen = MultiByteToWideChar(CP_ACP, 0, tstr, -1, NULL, 0);
    if (wideLen == 0) return NULL;

    wchar_t* wideStr = (wchar_t*)malloc(wideLen * sizeof(wchar_t));
    if (!wideStr) return NULL;

    if (!MultiByteToWideChar(CP_ACP, 0, tstr, -1, wideStr, wideLen)) {
        free(wideStr);
        return NULL;
    }

    int utf8Len = WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, NULL, 0, NULL, NULL);
    if (utf8Len == 0) {
        free(wideStr);
        return NULL;
    }

    char* utf8Str = (char*)malloc(utf8Len * sizeof(char));
    if (!utf8Str) {
        free(wideStr);
        return NULL;
    }

    WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, utf8Str, utf8Len, NULL, NULL);
    free(wideStr);
    return utf8Str;
#endif
}

注意事项

  • 转换后的字符串由malloc分配内存,调用者必须使用free释放,避免内存泄漏。
  • 若转换失败,函数返回NULL,可通过GetLastError()获取具体错误码排查问题。
  • DLL中调用这些Windows API无需修改区域设置,不会影响宿主程序的locale状态。
  • 确保项目的UNICODE/_MBCS宏定义与TCHAR的实际类型匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 15:35:01