LPSTR LPCTSTR解释

LPSTR LPCTSTR explanation

我有以下 C++ 代码:

#include "stdafx.h"
#include <atlstr.h>

int _tmain(int argc, _TCHAR* argv[])
{
    CString OFST_PATH;
    TCHAR DIR_PATH[MAX_PATH];

    GetCurrentDirectory(MAX_PATH, DIR_PATH);

    OFST_PATH.Format(DIR_PATH);

    CHAR *pOFST_PATH = (LPSTR)(LPCTSTR)OFST_PATH;

    return 0;
}

想明白为什么程序最后pOFST_PATH的值是"c"? (LPSTR)(LPCTSTR) 变量 OFST_PATH 的转换对其中写入的整个路径做了什么?

正如您在下面window中看到的,调试时变量值是:

CStringLPCTSTR 都基于 TCHAR,当定义了 UNICODE 时,它是 wchar_t(在您的情况下,正如我可以通过调试器中 argv 的值判断的那样)。当您这样做时:

(LPCTSTR)OFST_PATH

可以正常工作,因为 CString 有一个到 LPCTSTR 的转换运算符。但是如果定义了 UNICODELPCTSTR 就是 LPCWSTR、a.k.a。 wchar_t const*。它指向一个 utf16 字符数组。该数组中的第一个字符是 L'c'(这是 'c' 的宽字符版本)。 L'c' 的字节在内存中看起来像这样:0x63 0x00。这是字母 'c' 的 ASCII 代码,后跟一个零。因此,当您将 CString 转换为 LPCTSTR 时,这是有效的,但是,您的下一次转换:

(LPSTR)(LPCTSTR)OFST_PATH

这是无效的。 LPSTRchar*,因此您将 wchar_t const* 视为 char*。好吧,您的调试器假定当它看到 char* 时,它正在查看一个空终止的窄字符串。如果你记得上面第一个字符的字节值是什么,它是字母 'c' 的 ASCII 值,后跟一个零。因此调试器将其视为仅由字母 'c'.

组成的空终止字符串

这个故事的寓意是,如果您不了解它们的作用以及它们是否合适,请不要使用 C 风格的强制转换。