2011-10-07 48 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。我很驚訝你沒有收到編譯器警告。