Это два совершенно разных L . Первый является частью синтаксиса языка C ++.Префикс строкового литерала с L
, и он становится wide string literal;вместо массива char
вы получаете массив wchar_t
.
Однако L
в LPCWSTR
не описывает ширину символов.Вместо этого он описывает размер указателя .Или, по крайней мере, это раньше .Аббревиатура L
для имен типов является пережитком 16-битной Windows, когда существовало два вида указателей.Были указатели около , где адрес находился где-то внутри текущего сегмента размером 64 КБ, и указатели far или long , которые могли указывать за пределы текущегосегмент.Операционная система требовала, чтобы вызывающие абоненты предоставляли последний своим API-интерфейсам, поэтому все имена типов указателей используют LP
.В настоящее время есть только один тип указателя;Microsoft сохраняет те же имена типов, чтобы старый код продолжал компилироваться.
Часть LPCWSTR
, которая задает широкие символы, - это W
.Но простого преобразования типа char
строкового литерала в LPCWSTR
недостаточно для преобразования этих символов в широкие символы.Вместо этого то, что происходит, - приведение типа сообщает компилятору, что то, что вы написали , на самом деле является указателем на широкую строку, даже если на самом деле это не так.Компилятор доверяет вам.Не приводите тип, если вы действительно не знаете лучше, чем компилятор, что такое настоящие типы.
Если вам действительно нужно передать const char*
, тогда вам не нужнонаберите что-нибудь, и вам не нужен префикс L
.Достаточно простого старого строкового литерала.(Если вы действительно хотите привести к типу Windows, используйте LPCSTR
- нет W
.) Но похоже, что вам действительно нужно передать это const wchar_t*
.Как мы узнали выше, вы можете получить это с префиксом L
в строковом литерале.
В реальной программе у вас, вероятно, нет строкового литерала.Пользователь предоставит пароль, или вы прочитаете пароль из какого-либо другого внешнего источника.В идеале вы должны хранить этот пароль в std::wstring
, что похоже на std::string
, но для wchar_t
вместо char
.Метод c_str()
этого типа возвращает const wchar_t*
.Если у вас нет wstring
, может быть достаточно простого массива wchar_t
.
Но если вы храните пароль в std::string
, вам необходимо преобразовать егов широкие символы другим способом.Чтобы выполнить преобразование, вам необходимо знать, какую кодовую страницу используют символы std::string
.«Текущая кодовая страница ANSI» обычно является безопасной ставкой;он представлен константой CP_ACP
.Вы будете использовать это при вызове MultiByteToWideString
, чтобы ОС преобразовала кодовую страницу пароля в 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);