在托管C ++中返回奇怪的GetLastError

时间:2011-10-07 16:15:23

标签: c# c++ winapi getlasterror

我对GetLastError和托管C ++有一个非常奇怪的问题。从非托管代码转换为托管代码后,GetLastError返回一些非常奇怪的东西。

错误代码:122 - 传递给系统调用的数据区域太小。

此外,传入的strMessage正在向服务器发送。

非托管功能

   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;
   }

托管代码:

  void SendManagedMessage(String ^ strMessage)
  {
    CString cstrMessage = (char*) Marshal::StringToHGlobalAnsi(strMessage).ToPointer();
    CString cstrResponse;
       if (!SendMessage(cstrMessage, &cstrResponse))
       {
           Log("Failed to send managed message");
           Log(GetLastError());
       }

       //...
  }

记录输出

0
0
Failed!
Failed!
0
0
0
Failed to send managed message
122

2 个答案:

答案 0 :(得分:5)

许多功能会在执行工作时调用SetLastError作为副作用。通常,这意味着函数会调用其他函数,这些函数可能会有一些内部故障,可能会调用SetLastError,因此会覆盖先前的错误值。

作为一个例子,Log函数调用的东西很可能调用设置ERROR_INSUFFICIENT_BUFFER的东西,处理该错误并返回成功。结果?即使你的代码没有在更大的意义上失败,你的错误值也会被破坏。

当Win32函数失败时,在调用太多不相关的代码之前,需要注意调用GetLastError

更新:我还会阅读评论中的链接。此外,阅读你的代码,其中显示“失败”,然后是0错误代码,我认为可能发生的事情是另一端关闭套接字(即recv返回0)。

答案 1 :(得分:1)

您可能想尝试添加:

dwLastError = 0;

对于成功案例。你拥有它的方式,你可以使用未初始化的变量调用SetLastError。我很惊讶你没有得到编译器警告。