以下行导致GetLastError()
返回错误代码122(= ERROR_INSUFFICIENT_BUFFER)
CString str = CString("'") + _T("%s") + CString("'");
但这只发生在VS2005下,并且不会发生在VS2015中。我仍然看到VS2005中没有内存损坏或任何内容,str
变量确实包含正确的值。是否仍然需要关注提供错误代码?
这似乎发生的原因是因为宽字符和简单字符串的串联,并且修复是简单地用_T("")
覆盖剩余的字符串,所以代码行看起来像:
CString str = CString(_T("'")) + _T("%s") + CString(_T("'"));
但是当只有一个字符串是Unicode时,错误代码122在原始行中的含义是什么?在这种情况下,真正发生了什么错误或更像是警告?
答案 0 :(得分:4)
GetLastError()
仅在某些系统调用返回错误后才有意义。由于您的代码没有任何系统调用,GetLastError()
可以返回任何内容。
您看到的值可能是上次系统调用失败的最后一个错误。或者可能是CString
类内部发生的错误,但是在那里处理它。
TL; DR;这里没有错误。
答案 1 :(得分:2)
在VS 2015中,您可以使用CString("a")
(如果设置了Unicode)或仅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
函数可能是必要的,但在这种情况下,它会在下次调用{{1}时导致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