Strange GetLastError return in Managed C++
I have a really strange problem with GetLastError and managed C++. GetLastError is returning something very strange after transitioning from unmanaged code to managed code.
The error code: 122 - The data area passed to a system call is too small.
Additionally, the passed in strMessage is making it to the server.
Unmanaged function:
DWORD SendMessage(LPCTSTR strMessage, CString * strResponse)
{
DWORD dwLastError;
BOOL bSuccess = FALSE;
try
{
//some socket code
int ret = recv...
if (ret == SOCKET_ERROR || ret == 0)
{
Log(GetLastError()); //falls into here
Log(WSAGetLastError());
throw "Failed!"
}
bSuccess = TRUE;
}
catch (LPCTSTR pszException)
{
dwLastError = GetLastError();
Log(pszException);
Log(dwLastError );
Log(WSAGetLastError());
}
Log(dwLastError);
SetLastError(dwLastError);
return bSuccess;
}
Managed Code:
void SendManagedMessage(St开发者_开发百科ring ^ strMessage)
{
CString cstrMessage = (char*) Marshal::StringToHGlobalAnsi(strMessage).ToPointer();
CString cstrResponse;
if (!SendMessage(cstrMessage, &cstrResponse))
{
Log("Failed to send managed message");
Log(GetLastError());
}
//...
}
Log output
0
0
Failed!
Failed!
0
0
0
Failed to send managed message
122
Many functions will call SetLastError
as a side-effect while doing their work. Typically this means that a function calls some other function, which might have some internal failure for which it might call SetLastError
, and so the previous error value is overwritten.
As an example, it's quite likely that something called by the Log
function calls something that sets the ERROR_INSUFFICIENT_BUFFER
, handles that error, and returns success. Result? Even though your code didn't fail in a larger sense, your error value is clobbered.
When Win32 functions fail, you need to take some care to call GetLastError
before calling too much unrelated code.
Update: I would also read the link in the comment. Also, reading your code, where it says "Failed" followed by 0 error codes, I think likely what is happening is the other end closed the socket (i.e. recv
returned 0).
You may want to try adding:
dwLastError = 0;
For the success case. The way you have it, you can be calling SetLastError with an uninitialized variable. I am surprised you are not getting a compiler warning.
精彩评论