Странное возвращение GetLastError в Managed C ++ - PullRequest
1 голос
/ 07 октября 2011

У меня действительно странная проблема с 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 ]

5 голосов
/ 07 октября 2011

Многие функции будут вызывать SetLastError как побочный эффект при выполнении своей работы.Обычно это означает, что функция вызывает какую-то другую функцию, которая может иметь некоторый внутренний сбой, для которого она может вызвать SetLastError, и поэтому предыдущее значение ошибки перезаписывается.

Например, вполне вероятно, что что-тоВызванный функцией Log вызывает что-то, что устанавливает ERROR_INSUFFICIENT_BUFFER, обрабатывает эту ошибку и возвращает успех.Результат?Несмотря на то, что ваш код не был ошибочным в более широком смысле, значение вашей ошибки забито.

При сбое функций Win32 необходимо позаботиться о том, чтобы вызвать GetLastError, прежде чем вызывать слишком много несвязанного кода.

Обновление: Я бы тоже прочитал ссылку в комментарии.Кроме того, читая ваш код, где написано «Failed», за которым следуют 0 кодов ошибок, я думаю, вероятно, что происходит, когда другой конец закрыл сокет (то есть recv вернул 0).

1 голос
/ 07 октября 2011

Вы можете попробовать добавить:

dwLastError = 0;

Для успеха. Таким образом, вы можете вызывать SetLastError с неинициализированной переменной. Я удивлен, что вы не получаете предупреждение компилятора.

...