这是两个完全不同的L's.第一个是C++语言语法的一部分。字符串文字前缀为L
它变成了wide字符串字面量;而不是数组char
,你会得到一个数组wchar_t
.
The L
in LPCWSTR
但没有描述字符的宽度。相反,它描述了pointer。或者,至少,它used to. The L
类型名称的缩写是 16 位 Windows 的遗留物,当时有两种指针。有near指针,地址位于当前 64 KB 段内的某个位置,并且有far, or long指针,可以指向当前段之外。操作系统要求调用者向其 API 提供后者,因此所有指针类型名称都使用LP
。如今,只有一种类型的指针: Microsoft 保留相同的类型名称,以便旧代码可以继续编译。
的部分LPCWSTR
指定宽字符的是W
。但仅仅是类型转换char
字符串文字为LPCWSTR
不足以将这些字符转换为宽字符。相反,发生的情况是类型转换告诉编译器您编写的内容真的是指向宽字符串的指针,即使它实际上不是。编译器信任你。除非您确实比编译器更了解真正的类型,否则不要进行类型转换。
If you really需要通过一个const char*
,那么你不需要类型转换任何东西,也不需要任何L
字首。普通的旧字符串文字就足够了。 (如果您确实想转换为 Windows 类型,请使用LPCSTR
— no W
.) 但看起来你真正需要传递的是const wchar_t*
。正如我们上面了解到的,您可以通过L
字符串文字上的前缀。
在真实的程序中,您可能没有字符串文字。用户将提供密码,或者您将从其他外部源读取密码。理想情况下,您应该将该密码存储在std::wstring
,就像std::string
但对于wchar_t
代替char
. The c_str()
该类型的方法返回一个const wchar_t*
。如果你没有wstring
,一个普通数组wchar_t
可能就足够了。
但是如果您将密码存储在std::string
,那么您需要以其他方式将其转换为宽字符。要进行转换,您需要知道什么代码页 the std::string
字符使用。 “当前 ANSI 代码页”通常是一个安全的选择;它由常数表示CP_ACP
。调用时您将使用它MultiByteToWideString http://msdn.microsoft.com/en-us/library/dd319072.aspx让操作系统将密码的代码页转换为 Unicode。
int required_size = MultiByteToWideChar(CP_ACP, 0, vs[0].c_str(), vs[0].size(), NULL, 0);
if (required_size == 0)
ERROR;
// We'll be storing the Unicode password in this vector. Reserve at
// least enough space for all the characters plus a null character
// at the end.
std::vector<wchar_t> wv(required_size);
int result = MultiByteToWideChar(CP_ACP, 0, vs[0].c_str(), vs[0].size(), &wv[0], required_size);
if (result != required_size - 1)
ERROR;
现在,当你需要一个wchar_t*
,只需使用指向该向量的第一个元素的指针:&wv[0]
。如果您需要它wstring
,您可以通过几种方式从向量构造它:
// The vector is null-terminated, so use "const wchar_t*" constructor
std::wstring ws1 = &wv[0];
// Use iterator constructor. The vector is null-terminated, so omit
// the final character from the iterator range.
std::wstring ws2(wv.begin(), wv.end() - 1);
// Use pointer/length constructor.
std::wstring ws3(&wv[0], wv.size() - 1);