本文目录 5 个章节
Windows C++ 中的 LPCTSTR、Unicode 与字符串转换
类型关系
LPCTSTR 是 Windows 头文件中的历史兼容别名:
- 定义
UNICODE时,LPCTSTR等价于const wchar_t*。 - 未定义
UNICODE时,LPCTSTR等价于const char*。 LPCWSTR始终是const wchar_t*;LPCSTR始终是const char*。
新 Windows 项目通常直接使用 Unicode 版本的 API(名称以 W 结尾)和明确的 wchar_t/UTF-16 类型,避免让同一源代码因宏配置不同而改变字符类型。
L 前缀不是“转换”
const wchar_t* text = L"hello";
L"hello" 在编译期创建宽字符串字面量;它不是把运行时的窄字符串转换成宽字符串。Windows 上的 wchar_t 通常是 16 位,API 的宽字符串采用 UTF-16 编码单元。一个 Unicode 码点不一定只占一个 wchar_t,补充平面字符需要代理项对。
运行时转换
在 Windows API 边界,使用 MultiByteToWideChar 和 WideCharToMultiByte,并明确窄字符串的编码:
#include <windows.h>
#include <string>
#include <stdexcept>
std::wstring Utf8ToWide(const std::string& input) {
if (input.empty()) return {};
int count = MultiByteToWideChar(
CP_UTF8, MB_ERR_INVALID_CHARS,
input.data(), static_cast<int>(input.size()),
nullptr, 0);
if (count == 0) throw std::runtime_error("invalid UTF-8");
std::wstring output(count, L'\0');
MultiByteToWideChar(
CP_UTF8, MB_ERR_INVALID_CHARS,
input.data(), static_cast<int>(input.size()),
output.data(), count);
return output;
}
不要依赖系统当前代码页把 UTF-8 当作本地 ANSI 编码;也不要使用简单强制转换在 char* 与 wchar_t* 之间重解释内存。
TCHAR 与 _T()
TCHAR、LPCTSTR、TEXT()/_T() 用于早期同时构建 ANSI 和 Unicode 版本的代码。维护遗留项目时需要理解它们;新代码若只支持现代 Windows,可统一启用 Unicode,并在模块边界明确 UTF-8 与 UTF-16 的转换。