1

我对 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
4

2 回答 2

5

许多函数SetLastError在工作时会作为副作用调用。通常,这意味着一个函数调用了某个其他函数,该函数可能会调用一些内部故障SetLastError,因此之前的错误值会被覆盖。

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

当 Win32 函数失败时,GetLastError在调用太多无关代码之前需要小心调用。

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

于 2011-10-07T16:19:01.733 回答
1

您可能想尝试添加:

dwLastError = 0;

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

于 2011-10-07T16:38:34.687 回答