2011-10-07 1 views
1

J'ai un problème vraiment étrange avec GetLastError et géré C++. GetLastError renvoie quelque chose de très étrange après la transition du code non géré au code managé.Retour étrange GetLastError dans C++ géré

Le code d'erreur: 122 - La zone de données transmise à un appel système est trop petite.

En outre, le message strMessage transmis au serveur.

fonction non managée:

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; 
    } 

code managé:

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()); 
     } 

     //... 
    } 

sortie du journal

0 
0 
Failed! 
Failed! 
0 
0 
0 
Failed to send managed message 
122 
+0

Postez le code qui appelle 'recv()'. –

+0

Vous avez un bug dans votre code non géré - en utilisant la variable unitialized dwLastError. –

Répondre

5

Beaucoup func tions appellent SetLastError comme effet secondaire pendant leur travail. Cela signifie généralement qu'une fonction appelle une autre fonction, qui peut avoir une défaillance interne pour laquelle elle peut appeler SetLastError, et ainsi la valeur d'erreur précédente est remplacée.

Par exemple, il est très probable que quelque chose appelé par la fonction Log appelle quelque chose qui définit le ERROR_INSUFFICIENT_BUFFER, gère cette erreur et renvoie un succès. Résultat? Même si votre code n'a pas échoué dans un sens plus large, votre valeur d'erreur est coupée. Lorsque les fonctions Win32 échouent, vous devez prendre quelques précautions pour appeler le GetLastError avant d'appeler trop de code non apparenté.

Mise à jour: Je voudrais également lire le lien dans le commentaire. En outre, en lisant votre code, où il est dit "Failed" suivi de 0 codes d'erreur, je pense que ce qui se passe est probablement l'autre extrémité fermée le socket (c'est-à-dire recv retourné 0).

+1

Il semble également que vous ne puissiez pas appeler GetLastError à partir de C++ géré de manière fiable: http://blogs.msdn.com/b/adam_nathan/archive/2003/04/25/56643.aspx –

+0

@AdamDriscoll - +1. Je n'ai aucune expérience en la matière, donc je n'étais pas au courant de ces problèmes, mais je ne suis pas surpris. – asveikau

1

Vous pouvez essayer d'ajouter:

dwLastError = 0; 

Pour le cas de succès. La façon dont vous l'avez, vous pouvez appeler SetLastError avec une variable non initialisée. Je suis surpris que vous n'obteniez pas d'avertissement de compilateur.

Questions connexes