---
title: "Windows C++ 中的 `LPCTSTR`、Unicode 与字符串转换"
author: "Perrin Yong"
author_profile: https://www.pystone.net/profile/
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/cpp-windows-lpctstr-unicode-string/
type: note
content_role: unspecified
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/02-编程语言与运行时/C++/LPCTSTR及其相关.md"
content_hash: a4c2fd82dd41eff4c740a5d895aa462b4fda90a647af9cfce5f6c2fc0629d811
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# 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` 前缀不是“转换”

```cpp
const wchar_t* text = L"hello";
```

`L"hello"` 在编译期创建宽字符串字面量；它不是把运行时的窄字符串转换成宽字符串。Windows 上的 `wchar_t` 通常是 16 位，API 的宽字符串采用 UTF-16 编码单元。一个 Unicode 码点不一定只占一个 `wchar_t`，补充平面字符需要代理项对。

## 运行时转换

在 Windows API 边界，使用 `MultiByteToWideChar` 和 `WideCharToMultiByte`，并明确窄字符串的编码：

```cpp
#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 的转换。

## 参考资料

- [Microsoft Learn：Working with Strings](https://learn.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings)
- [Microsoft Learn：String and Character Literals](https://learn.microsoft.com/en-us/cpp/cpp/string-and-character-literals-cpp?view=msvc-170)
