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、そのエラーを処理し、成功を返すものを呼び出す可能性が非常に高くなります。結果?あなたのコードはより広い意味で失敗しなかったとしても、あなたのエラー値は壊滅的です。

GetLastErrorWin32関数が失敗した場合は、無関係なコードを呼び出す前に、注意して呼び出す必要があります。

更新:コメントのリンクも読みます。recvまた、「Failed」の後に0のエラーコードが続くコードを読むと、もう一方の端がソケットを閉じている(つまり0が返されている)可能性が高いと思います。

于 2011-10-07T16:19:01.733 に答える
1

以下を追加してみてください:

dwLastError = 0;

成功例の場合。あなたのやり方では、初期化されていない変数で SetLastError を呼び出すことができます。コンパイラの警告が表示されないことに驚いています。

于 2011-10-07T16:38:34.687 に答える