2011-10-07 86 views
1

GetLastError和托管C++有一个非常奇怪的问题。从非托管代码转换为托管代码后,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 
+0

发布调用'recv()'的代码。 –

+0

您的非托管代码中存在一个错误 - 使用单位变量dwLastError。 –

回答

5

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

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

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

更新:我也会阅读评论中的链接。另外,阅读你的代码,它说“失败”,后面跟着0个错误代码,我想可能发生的是另一端关闭了套接字(即recv返回0)。

+1

它也看起来像你不能从托管的C++可靠地调用GetLastError:http://blogs.msdn.com/b/adam_nathan/archive/2003/04/25/56643.aspx –

+0

@AdamDriscoll - +1。我没有任何尝试这样做的经验,所以我没有意识到这些问题,但我并不感到惊讶。 – asveikau

1

你可能想尝试添加:

dwLastError = 0; 

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