IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

probleme avec HRESULT


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Par défaut probleme avec HRESULT
    Bonjour,

    J'utilise ce petit bout de code ci-dessous:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    HRESULT reponse;
      reponse=CoGetClassObject(CLSID_TTestServeurCOM, CLSCTX_REMOTE_SERVER, NULL, IID_ITestServeurCOM, &distributedObject);
     
      switch(reponse){
                      case S_OK:
                           std::cout << "Location and connection to the specified class object was successful." << std::endl;
                           break;  
                      case REGDB_E_CLASSNOTREG:
                           std::cout << "CLSID is not properly registered. Can also indicate that the value you specified in dwClsContext is not in the registry." << std::endl;
                           break;
                      case E_NOINTERFACE:
                           std::cout << "Either the object pointed to by ppv does not support the interface identified by riid, or the QueryInterface operation on the class object returned E_NOINTERFACE." << std::endl;
                           break;
                      case REGDB_E_READREGDB:
                           std::cout << "Error reading the registration database." << std::endl;
                           break;
                      case CO_E_DLLNOTFOUND:
                           std::cout << "In-process DLL or handler DLL not found (depends on context)." << std::endl;
                           break;
                      case CO_E_APPNOTFOUND:
                           std::cout << "EXE not found (CLSCTX_LOCAL_SERVER only)." << std::endl;
                           break;
                      case E_ACCESSDENIED:
                           std::cout << "General access failure (returned from LoadLib/CreateProcess)." << std::endl;
                           break;
                      case CO_E_ERRORINDLL:
                           std::cout << "EXE has error in image." << std::endl;
                           break; 
                      case CO_E_APPDIDNTREG:
                           std::cout << "EXE was launched, but it didn't register class object (may or may not have shut down)." << std::endl;
                           break;
                      default:
                           std::cout << "Reponse inconnue???: " << reponse << std::endl;
                           break;
      }
    La fonction CoGetClassObject vient d'une librairie Microsoft. D'apres la doc en ligne, elle renvoi des codes d'erreurs HRESULT. Tous ce qu'elle peut renvoyée est dans le switch.

    Probleme: je passe toujours dans le default.

    Quelqu'un a-t-il une idée?

  2. #2
    Membre chevronné Avatar de themadmax
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 446
    Par défaut
    Donne le code de ton erreur, dans visual studio tu as un outil pour faire la correspondance entre le erreur COM et sa definition.

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Et si tu donnes le code d'erreur, donne-le en hexadécimal.

    PS: Je te déconseille de tester directement S_OK dans le switch, sauf pour des fonctions où la distinction entre S_OK et S_FALSE est bien documentée.
    Tu devrais tester S_OK dans le default avec la macro SUCCEEDED().
    ...Ou bien, ne passer dans le switch que si la fonction a échoué (la macro SUCCEEDED() retourne vrai ou la macro FAILED() retourne faux)...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    En fait, je parie que ton erreur est CO_E_NOTINITIALIZED (0x800401F0) et que tu as oublié d'appeler CoInitialize() avant CoGetClassObject().
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre éclairé Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Par défaut
    En fait, je parie que ton erreur est CO_E_NOTINITIALIZED (0x800401F0) et que tu as oublié d'appeler CoInitialize() avant CoGetClassObject().
    Medinoc tu as bien deviné.

  6. #6
    Membre éclairé Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Par défaut
    Bon, tant que je suis la, je continue.

    Maintenant, j'appelle la fonction CoInitialize() qui me retourne S_OK.

    Par contre, au niveau du CoGetClassObject(), j'ai en retour:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    REGDB_E_CLASSNOTREG: "CLSID is not properly registered. Can also indicate that the value you specified in dwClsContext is not in the registry."
    Pour résumé, coté serveur, j'ai une dll que j'enregistre avec ce petit .exe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        TCOMITestServeurCOMT<TTestServeurCOM> serveur = CoTTestServeurCOM::Create();
        IUnknown * serveurPtr = serveur;
        LPDWORD objectNumber;
        int reponse=CoRegisterClassObject(CLSID_TTestServeurCOM, serveurPtr, CLSCTX_REMOTE_SERVER, REGCLS_MULTI_SEPARATE, objectNumber);
     
        if(reponse==S_OK)
                        std::cout << "Serveur enregistre: " << objectNumber << std::endl;
        else
                        std::cout << "Serveur NON enregistre." << std::endl;
    Quand j'execute cela, ca donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Serveur enregistre: 409028
    Et pourtant, il ne le voit pas.
    Remarque: les 2 objets sont pour l'instant sur la même machine.

    Une idée de pourquoi il ne le voit pas comme enregistré?

    P.S. : désolé, j'ai pas encore modifié le code pour utiliser succeeded().

  7. #7
    Membre éclairé Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Et si tu donnes le code d'erreur, donne-le en hexadécimal.
    Je vais encore passer pour un con, mais comment je fais pour me l'afficher en hexa?

    En fait c'est bon j'ai trouvé (mais j'ai galeré), il suffit de faire ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::cout << std::hex << codeErreur;

  8. #8
    Membre éclairé Avatar de sylvain.cool
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Par défaut
    C'est bon, ça marche en local avec CoCreateInstanceEx.

    Par contre, depuis un autre PC, non. J'obtiens l'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    E_NOINTERFACE: "None of the interfaces requested in the pResults array were successfully retrieved."
    Je donne à la fonction CoCreateInstanceEx le nom du PC sur lequel il doit aller chercher l'objet. Par contre, je ne lui donne aucune infos sur comment se connecter au PC (login et autres).

    Ce qui est sur, c'est qu'il trouve le PC puisque si je donne un mauvais nom, il me le dit.
    Mais si il n'arrivait pas à s'y connecter pour trouver l'objet, il devrait me le dire aussi, non?



    De plus, quand j'enregistre l'objet sur le serveur avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CoRegisterClassObject(CLSID_TTestServeurCOM, serveurPtr, CLSCTX_REMOTE_SERVER|CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, objectNumber)
    Avec cela, j'obtiens l'erreur ci-dessus.
    Mais maintenant que j'essaie depuis un autre PC, je met:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CoRegisterClassObject(CLSID_TTestServeurCOM, serveurPtr, CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE, objectNumber)
    Et la, depuis le client je ai une autre erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    REGDB_E_CLASSNOTREG: "A specified class is not registered in the registration database. Also can indicate that the type of server you requested in the CLSCTX enumeration is not registered or the values for the server types in the registry are corrupt."
    Je trouve ça bizarre qu'en enlevant le LOCAL, ça change quelque chose sur le client situé sur un autre PC.


    Code actuel:
    Serveur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
        TCOMITestServeurCOMT<TTestServeurCOM> serveur = CoTTestServeurCOM::Create();
        IUnknown * serveurPtr = serveur;
        LPDWORD objectNumber = new DWORD;
        //int reponse;
     
        // On enregistre le serveur
        if(SUCCEEDED(CoRegisterClassObject(CLSID_TTestServeurCOM, serveurPtr, CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE, objectNumber)))
                        std::cout << "Serveur enregistre: " << *objectNumber << std::endl;
        else
                        std::cout << "Serveur NON enregistre."  << std::endl;
     
        // On attend une connexion
        MessageBox(NULL, TEXT("Cliquer OK pour quitter"), TEXT("Serveur COM"), MB_OK);
     
        std::cout << std::endl;
     
        // On dereference l'objet
        if(SUCCEEDED(CoRevokeClassObject(*objectNumber)))
                        std::cout << "Serveur desenregistre: " << *objectNumber << std::endl;
        else
                        std::cout << "Serveur NON desenregistre."  << std::endl;
     
        system("PAUSE");
    client:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
     
      HRESULT reponse; 
      TCOMITestServeurCOMT<TTestServeurCOM> serveur; 
     
     
     
      std::cout<< "Initialize: " << std::endl;
      if(!SUCCEEDED(reponse=CoInitialize(NULL)))  
           switch(reponse){
                          case S_OK:
                               std::cout << "The COM library was initialized successfully on this thread." << std::endl;
                               break;  
                          case S_FALSE:
                               std::cout << "The COM library is already initialized on this thread.." << std::endl;
                               break;
                          case RPC_E_CHANGED_MODE:
                               std::cout << "A previous call to CoInitializeEx specified the concurrency model for this thread as multithread apartment (MTA). If running Windows 2000, this could also mean that a change from neutral-threaded apartment to single-threaded apartment occurred." << std::endl;
                               break;
                          default:
                               std::cout << "Reponse inconnue???: 0x" << std::hex << reponse << std::endl;
                               break;
           }
      else
          std::cout << "The COM library was initialized successfully on this thread." << std::endl;
     
     
     
      std::cout << std::endl << "CoCreateInstanceEx: " << std::endl;
     
      // Création de la structure MULTI_QI
      MULTI_QI multiQiRes;
      multiQiRes.pIID = &IID_ITestServeurCOM, //& IID_IUnknown;
      multiQiRes.pItf = NULL;   
      multiQiRes.hr = 0;
     
      //Creation du COSERVERINFO
      COSERVERINFO serveurInfo;
      wchar_t serveurName[] = L"UC06P1556.fr.pierre-fabre.lcl";  
      serveurInfo.pwszName = serveurName;
      serveurInfo.pAuthInfo = NULL;
      serveurInfo.dwReserved1 = 0; 
      serveurInfo.dwReserved2 = 0;
     
      reponse=CoCreateInstanceEx(CLSID_TTestServeurCOM, NULL, CLSCTX_REMOTE_SERVER, &serveurInfo, 1, &multiQiRes);
      //CLSCTX_REMOTE_SERVER|CLSCTX_LOCAL_SERVER
     
      if(!SUCCEEDED(reponse))
          switch(reponse){ 
    					  case REGDB_E_CLASSNOTREG:
                               std::cout << "A specified class is not registered in the registration database. Also can indicate that the type of server you requested in the CLSCTX enumeration is not registered or the values for the server types in the registry are corrupt." << std::endl;
                               break;
    					  case E_NOINTERFACE:
                               std::cout << "None of the interfaces requested in the pResults array were successfully retrieved." << std::endl;
    						   break;
    					  case CLASS_E_NOAGGREGATION:
    						   std::cout << "This class cannot be created as part of an aggregate." << std::endl;
    						   break; 
    					  case CO_S_NOTALLINTERFACES:
    						   std::cout << "At least one, but not all of the interfaces requested in the pResults array were successfully retrieved. The hr field of each of the MULTI_QI structures in pResults indicates with S_OK or E_NOINTERFACE whether the specific interface was returned." << std::endl;
    						   break;
                          default:
    						   std::cout << "Reponse inconnue???: 0x" << std::hex << reponse << std::endl;
                               break;
          } 
      else{
           std::cout << "Location and connection to the specified class object was successful." << std::endl;
           serveur = static_cast< ITestServeurCOM * >(multiQiRes.pItf);
      }
     
     
     
      if( SUCCEEDED(reponse) ){  
                 std::cout << std::endl << "Appel de l'objet distant:" << std::endl;
                 std::wcout << "Nombre de processeurs: " << serveur.Nombre << " et voila." << std::endl;
      }
     
      system("PAUSE");

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Typiquement, il faut que la DLL contenant le proxy de ton interface soit installée et enregistrée sur le poste client.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Probleme avec la copie des surfaces
    Par Black_Daimond dans le forum DirectX
    Réponses: 3
    Dernier message: 09/01/2003, 10h33
  2. Problèmes avec le filtrage des ip
    Par berry dans le forum Réseau
    Réponses: 9
    Dernier message: 30/12/2002, 07h51
  3. probleme avec la touche F10
    Par b.grellee dans le forum Langage
    Réponses: 2
    Dernier message: 15/09/2002, 22h04
  4. Probleme avec fseek
    Par Bjorn dans le forum C
    Réponses: 5
    Dernier message: 04/08/2002, 07h17
  5. [Kylix] probleme avec un imagelist
    Par NicoLinux dans le forum EDI
    Réponses: 4
    Dernier message: 08/06/2002, 23h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo