[C++] Appel à une méthode récupérée par pointeur

Appel à une méthode récupérée par pointeur [C++] - C++ - Programmation

Marsh Posté le 24-08-2004 à 11:22:54    

Le programme plante lamentablement lors de l'appel à la méthode Open de ITarmedValidator. Quelqu'un a-t-il une idée ?
 

Code :
  1. ...
  2. enum LanguageType{enGerman, enFrench, enItalian, enEnglish};
  3. ...
  4. struct ITarmedValidator : public IUnknown
  5. {
  6.     virtual HRESULT STDMETHODCALLTYPE Open(LanguageType enLanguage,
  7.                                            VARIANT_BOOL *pbStatus)=0;
  8. };
  9. ...
  10. ITarmedValidator * pITarmedValidator;
  11. DllCOM * tv_dll;
  12. ...
  13. tv_dll = new DllCOM(dll);
  14. ...
  15. void * pv;
  16. tv_dll->SwitchInterface(iid_ITarmedValidator, pv);
  17. pITarmedValidator = (ITarmedValidator *)pv;
  18. ...
  19. VARIANT_BOOL * p;
  20. HRESULT res;
  21. MessageBox(NULL, "ok 1", "open", 0);
  22. res = pITarmedValidator->Open(enFrench, p);
  23. ...


Méthode SwitchInterface de DllCOM :

Code :
  1. void DllCOM::SwitchInterface(IID iidNew, void * pv)
  2. {
  3.     pIUnknown->QueryInterface(iidNew, &pv);
  4. }


Message édité par fatypunk le 24-08-2004 à 13:53:42
Reply

Marsh Posté le 24-08-2004 à 11:22:54   

Reply

Marsh Posté le 24-08-2004 à 11:25:32    

ben normal, hein, pv est pas initialisé entre sa déclaration et la ou tu le cast en ITarmed (ton switchInterface modifie le contenue d'une var locale). Pis d'ailleurs tu le delete apres (?)

Reply

Marsh Posté le 24-08-2004 à 11:30:14    

chrisbk a écrit :

ben normal, hein, pv est pas initialisé entre sa déclaration et la ou tu le cast en ITarmed (ton switchInterface modifie le contenue d'une var locale). Pis d'ailleurs tu le delete apres (?)


 
Non le delete après c'est une bourde que j'ai ajouté au message... corrigé

Reply

Marsh Posté le 24-08-2004 à 11:31:42    

si j'etais toi :
 

Code :
  1. tv_dll->SwitchInterface(iid_ITarmedValidator, &pv);
  2. ...
  3. void DllCOM::SwitchInterface(IID iidNew, void** pv)
  4. {
  5.       pIUnknown->QueryInterface(iidNew, pv);
  6. }

Reply

Marsh Posté le 24-08-2004 à 11:32:29    

Il est initialiser dans CreateInstance (j'avais pas posté)

Code :
  1. tv_dll = new DllCOM(dll);
  2.     tv_dll->CreateInstance(clsid_TarmedValidator);
  3.     ITarmedValidator * pITarmedValidator;
  4.    
  5.     void * pv;
  6.     tv_dll->SwitchInterface(iid_ITarmedValidator, pv);
  7.     pITarmedValidator = (ITarmedValidator *)pv;
  8.     VARIANT_BOOL * p;
  9.     HRESULT res;
  10.     res = pITarmedValidator->Open(enFrench, p);


Code :
  1. void DllCOM::CreateInstance(CLSID clsid)
  2.     void * pv;
  3.     switch (CoCreateInstance(clsid, NULL, CLSCTX_ALL, iid_IUnknown, &pv))
  4.     {
  5.     case S_OK :
  6.         MessageBox(NULL, "ok", "CreateInstance", 0);
  7.         break;
  8.     case REGDB_E_CLASSNOTREG :
  9.         MessageBox(NULL, "REGDB_E_CLASSNOTREG", "CreateInstance", 0);
  10.         break;
  11.     case CLASS_E_NOAGGREGATION :
  12.         MessageBox(NULL, "CLASS_E_NOAGGREGATION", "CreateInstance", 0);
  13.         break;
  14.     case E_NOINTERFACE :
  15.         MessageBox(NULL, "E_NOINTERFACE", "CreateInstance", 0);
  16.         break;
  17.     }
  18.     pIUnknown = (IUnknown *)pv;
  19. }


Message édité par fatypunk le 24-08-2004 à 13:51:20
Reply

Marsh Posté le 24-08-2004 à 11:34:08    

Ah oui j'ai compris je crois...

Reply

Marsh Posté le 24-08-2004 à 11:37:47    

Ah bein non, ca marche toujours pas :

Code :
  1. void DllCOM::SwitchInterface(IID iidNew, void ** pv)
  2. {
  3.     pIUnknown->QueryInterface(iidNew, pv);
  4. }


Code :
  1. tv_dll = new DllCOM(dll);
  2.     tv_dll->CreateInstance(clsid_TarmedValidator);
  3.     ITarmedValidator * pITarmedValidator;
  4.    
  5.     void * pv;
  6.     tv_dll->SwitchInterface(iid_ITarmedValidator, &pv);
  7.     pITarmedValidator = (ITarmedValidator *)pv;
  8.     VARIANT_BOOL * p;
  9.     HRESULT res;
  10.     res = pITarmedValidator->Open(enFrench, p);


Message édité par fatypunk le 24-08-2004 à 13:51:46
Reply

Marsh Posté le 24-08-2004 à 11:38:56    

ben verifie le retour de ton QueryInterface, ce genre de truc

Reply

Marsh Posté le 24-08-2004 à 11:43:58    

chrisbk a écrit :

ben verifie le retour de ton QueryInterface, ce genre de truc


 
Il renvoie bien S_OK...

Reply

Marsh Posté le 24-08-2004 à 12:05:14    

Code :
  1. struct ITarmedValidator : public IUnknown
  2. {
  3.     virtual HRESULT STDMETHODCALLTYPE Open(LanguageType enLanguage,
  4.                                            VARIANT_BOOL *pbStatus)=0;
  5. };


Je suis pas mauvais en C mais encore débutant en C++, mais il me semble que tu défini (ou redéfini) une méthode virtuelle pure ("virtual method() = 0;" ). Ce type de déclaration est employé dans des classes abstraites. Elles ne peuvent pas être employées directement mais uniquement via une classe dérivée dans laquelle il faut obligatoirement redéfinir les méthodes virtuelles pures. Sinon, c'est un peu comme si tu appelais une fonction via un pointeur NULL.
Il faut donc que tu écrives le code de la méthode Open().

Reply

Marsh Posté le 24-08-2004 à 12:05:14   

Reply

Marsh Posté le 24-08-2004 à 12:20:46    

lsdyoyo a écrit :

Je suis pas mauvais en C mais encore débutant en C++, mais il me semble que tu défini (ou redéfini) une méthode virtuelle pure ("virtual method() = 0;" ). Ce type de déclaration est employé dans des classes abstraites. Elles ne peuvent pas être employées directement mais uniquement via une classe dérivée dans laquelle il faut obligatoirement redéfinir les méthodes virtuelles pures. Sinon, c'est un peu comme si tu appelais une fonction via un pointeur NULL.
Il faut donc que tu écrives le code de la méthode Open().


 
La méthode fait partie de la classe contenue dans la dll compilée que j'utilise. Si je devais ré-écrire le code de la dll, elle ne me servirait à rien...
 
Il est cependant obligatoire de la déclarer, sinon le compilo râlerait pour classe et méthode inconnnues...
 
Maintenant peut-être que ma facon de procéder est fausse, je suis pas un spécialiste...


Message édité par fatypunk le 24-08-2004 à 13:30:42
Reply

Marsh Posté le 24-08-2004 à 13:55:18    

chrisbk a écrit :

ben verifie tes appels, la tronche du pointeur retouré, ou exactement ca plante, comment ca plante...


 
Ca plante sur l'appel à Open.
Et comment tu vérifie la tronche du pointeur ?


Message édité par fatypunk le 24-08-2004 à 13:56:01
Reply

Marsh Posté le 24-08-2004 à 13:57:04    

fatypunk a écrit :

Et comment tu vérifie la tronche du pointeur ?


 
avec un fin debugueur ? Si ca plante *lors* de l'appel et que ton ptr a l'air valide alors verifie ta declaration de ptranslatemachin, des fois que ca debloquerait dans les vtables

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed