Следующая строка приводит к GetLastError()
вернуть код ошибки 122 (= ERROR_INSUFFICIENT_BUFFER)
CString str = CString("'") + _T("%s") + CString("'");
Но это происходит только под VS2005 и не происходит в VS2015. Тем не менее я не вижу повреждения памяти или что-нибудь в VS2005 и str
переменная содержит правильное значение. Это все еще проблема, о которой нужно беспокоиться, дайте код ошибки?
Причина, по которой это происходит, заключается в объединении строк широких символов и простых символов, и исправление состоит в том, чтобы просто распределить обе оставшиеся строки с помощью _T("")
поэтому строка кода будет выглядеть так:
CString str = CString(_T("'")) + _T("%s") + CString(_T("'"));
Но что на самом деле означает код ошибки 122 в исходной строке, когда только одна строка была Unicode? Что плохого действительно произошло или это больше похоже на предупреждение в этом случае?
В VS 2015 вы можете воспроизвести ошибку с CString("a")
(если установлен Юникод) или просто CStringW("a")
#include <iostream>
#include <atlstr.h>
int main()
{
CStringW("a");
DWORD err = GetLastError();
std::cout << err << "\n"; //<= error 122, ERROR_INSUFFICIENT_BUFFER
return 0;
}
Это происходит потому, что CString
использует WinAPI MultiByteToWideChar
конвертировать ANSI "a"
Unicode L"a"
, Отладка через исходный код в "atlmfc\include\cstringt.h"
мы видим, что в какой-то момент он вызывает следующую функцию:
static int __cdecl GetBaseTypeLength(_In_z_ LPCSTR pszSrc) throw()
{
// Returns required buffer size in wchar_ts
return ::MultiByteToWideChar( _AtlGetConversionACP(), 0, pszSrc, -1, NULL, 0 )-1;
}
По какой-то причине существует -1
в конце. Я не знаю, почему это там, это может быть необходимо для других CString
функции, но в этом случае это в конечном итоге вызывает ERROR_INSUFFICIENT_BUFFER
ошибка при следующем вызове MultiByteToWideChar
, Преобразование может быть примерно упрощено следующим образом:
int main()
{
int nDestLength = MultiByteToWideChar(CP_ACP, 0, "a", -1, NULL, 0) - 1;
wchar_t *pszDest = new wchar_t[32];
//ERROR_INSUFFICIENT_BUFFER occurs here because nDestLength is short by 1:
MultiByteToWideChar(CP_ACP, 0, "a", -1, pszDest, nDestLength);
DWORD err = GetLastError();
std::cout << err << "\n";
return 0;
}
nDestLength
слишком мал, потому что он не учитывает нулевой терминатор. CString
разбирается с этим позже, но ошибка остается. Это хорошая причина не обращать внимания на GetLastError
если функция не работает.
Как вы заметили, этой ошибки можно избежать, используя _T
макрос, потому что CString
больше не нужно MultiByteToWideChar
, Или еще лучше, используйте L
префикс или CString::Format
CString str = CString(L"'") + L"%s" + CString(L"'");
GetLastError()
имеет смысл только после того, как какой-то системный вызов вернул ошибку. Поскольку в вашем коде нет системного вызова, GetLastError()
может вернуть все что угодно.
Возможно, значение, которое вы видите, является последней ошибкой последнего системного вызова, который не удался. Или, может быть, какая-то ошибка произошла изнутри CString
класс, но он обрабатывается там.
TL; DR; Здесь нет ошибок.