{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/cpp-windows-lpctstr-unicode-string/",
  "atlas": "https://www.pystone.net/?node=cpp-windows-lpctstr-unicode-string#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/cpp-windows-lpctstr-unicode-string.md",
  "context": "https://www.pystone.net/notes/cpp-windows-lpctstr-unicode-string.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:cpp-windows-lpctstr-unicode-string",
  "slug": "cpp-windows-lpctstr-unicode-string",
  "title": "Windows C++ 中的 `LPCTSTR`、Unicode 与字符串转换",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "Windows C++ 中的 LPCTSTR 、Unicode 与字符串转换",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "a4c2fd82dd41eff4c740a5d895aa462b4fda90a647af9cfce5f6c2fc0629d811",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "Windows C++ 中的 LPCTSTR、Unicode 与字符串转换",
      "anchor": "windows-c-中的-lpctstrunicode-与字符串转换",
      "citation": "https://www.pystone.net/notes/cpp-windows-lpctstr-unicode-string/#windows-c-%E4%B8%AD%E7%9A%84-lpctstrunicode-%E4%B8%8E%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BD%AC%E6%8D%A2"
    },
    {
      "depth": 2,
      "text": "类型关系",
      "anchor": "类型关系",
      "citation": "https://www.pystone.net/notes/cpp-windows-lpctstr-unicode-string/#%E7%B1%BB%E5%9E%8B%E5%85%B3%E7%B3%BB"
    },
    {
      "depth": 2,
      "text": "L 前缀不是“转换”",
      "anchor": "l-前缀不是转换",
      "citation": "https://www.pystone.net/notes/cpp-windows-lpctstr-unicode-string/#l-%E5%89%8D%E7%BC%80%E4%B8%8D%E6%98%AF%E8%BD%AC%E6%8D%A2"
    },
    {
      "depth": 2,
      "text": "运行时转换",
      "anchor": "运行时转换",
      "citation": "https://www.pystone.net/notes/cpp-windows-lpctstr-unicode-string/#%E8%BF%90%E8%A1%8C%E6%97%B6%E8%BD%AC%E6%8D%A2"
    },
    {
      "depth": 2,
      "text": "TCHAR 与 T()",
      "anchor": "tchar-与-t",
      "citation": "https://www.pystone.net/notes/cpp-windows-lpctstr-unicode-string/#tchar-%E4%B8%8E-t"
    },
    {
      "depth": 2,
      "text": "参考资料",
      "anchor": "参考资料",
      "citation": "https://www.pystone.net/notes/cpp-windows-lpctstr-unicode-string/#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:programming-languages-and-runtimes",
      "title": "编程语言与运行时",
      "url": "https://www.pystone.net/notes/programming-languages-and-runtimes/",
      "atlas": "https://www.pystone.net/?node=programming-languages-and-runtimes#knowledge-atlas",
      "label": "编程语言与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "C++中的“LPCTSTR及其相关”导航项",
      "citation": "https://www.pystone.net/notes/programming-languages-and-runtimes/#c"
    }
  ],
  "contentMarkdown": "# Windows C++ 中的 `LPCTSTR`、Unicode 与字符串转换\n\n## 类型关系\n\n`LPCTSTR` 是 Windows 头文件中的历史兼容别名：\n\n- 定义 `UNICODE` 时，`LPCTSTR` 等价于 `const wchar_t*`。\n- 未定义 `UNICODE` 时，`LPCTSTR` 等价于 `const char*`。\n- `LPCWSTR` 始终是 `const wchar_t*`；`LPCSTR` 始终是 `const char*`。\n\n新 Windows 项目通常直接使用 Unicode 版本的 API（名称以 `W` 结尾）和明确的 `wchar_t`/UTF-16 类型，避免让同一源代码因宏配置不同而改变字符类型。\n\n## `L` 前缀不是“转换”\n\n```cpp\nconst wchar_t* text = L\"hello\";\n```\n\n`L\"hello\"` 在编译期创建宽字符串字面量；它不是把运行时的窄字符串转换成宽字符串。Windows 上的 `wchar_t` 通常是 16 位，API 的宽字符串采用 UTF-16 编码单元。一个 Unicode 码点不一定只占一个 `wchar_t`，补充平面字符需要代理项对。\n\n## 运行时转换\n\n在 Windows API 边界，使用 `MultiByteToWideChar` 和 `WideCharToMultiByte`，并明确窄字符串的编码：\n\n```cpp\n#include <windows.h>\n#include <string>\n#include <stdexcept>\n\nstd::wstring Utf8ToWide(const std::string& input) {\n    if (input.empty()) return {};\n\n    int count = MultiByteToWideChar(\n        CP_UTF8, MB_ERR_INVALID_CHARS,\n        input.data(), static_cast<int>(input.size()),\n        nullptr, 0);\n    if (count == 0) throw std::runtime_error(\"invalid UTF-8\");\n\n    std::wstring output(count, L'\\0');\n    MultiByteToWideChar(\n        CP_UTF8, MB_ERR_INVALID_CHARS,\n        input.data(), static_cast<int>(input.size()),\n        output.data(), count);\n    return output;\n}\n```\n\n不要依赖系统当前代码页把 UTF-8 当作本地 ANSI 编码；也不要使用简单强制转换在 `char*` 与 `wchar_t*` 之间重解释内存。\n\n## `TCHAR` 与 `_T()`\n\n`TCHAR`、`LPCTSTR`、`TEXT()`/`_T()` 用于早期同时构建 ANSI 和 Unicode 版本的代码。维护遗留项目时需要理解它们；新代码若只支持现代 Windows，可统一启用 Unicode，并在模块边界明确 UTF-8 与 UTF-16 的转换。\n\n## 参考资料\n\n- [Microsoft Learn：Working with Strings](https://learn.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings)\n- [Microsoft Learn：String and Character Literals](https://learn.microsoft.com/en-us/cpp/cpp/string-and-character-literals-cpp?view=msvc-170)\n"
}
