[C++] Recuperer l'adresse d'une fonction virtuelle pure [modified]

Recuperer l'adresse d'une fonction virtuelle pure [modified] [C++] - C++ - Programmation

Marsh Posté le 01-09-2003 à 20:44:18    

J'offre pomme a celui qui m'explique pourquoi :

Code :
  1. m_lpVertexShader->setFloatConstantf(NULL,2.0f);
  2. 0058830B 8B F4            mov         esi,esp
  3. 0058830D 68 00 00 00 40   push        40000000h
  4. 00588312 6A 00            push        0   
  5. 00588314 8B 45 E8         mov         eax,dword ptr [this]
  6. 00588317 8B 48 08         mov         ecx,dword ptr [eax+8]
  7. 0058831A 51               push        ecx 
  8. 0058831B 8B 55 E8         mov         edx,dword ptr [this]
  9. 0058831E 8B 42 08         mov         eax,dword ptr [edx+8]
  10. 00588321 8B 08            mov         ecx,dword ptr [eax]
  11. 00588323 FF 51 2C         call        dword ptr [ecx+2Ch]
  12. 00588326 3B F4            cmp         esi,esp
  13. 00588328 E8 A9 E8 F0 FF   call        @ILT+23505(__RTC_CheckEsp) (496BD6h)


 
 
POurquoi cet ane baté de visual push ECX !
Bref qui qui a la convention d'appel de fonction virtuelle sous la main ? [:cupra]
 
 
 
 
Anciennement :
 
vala, j'ai un objet genre :
 
 

Code :
  1. class IVertexShader
  2. {
  3. public:
  4. virtual void setFloatConstant()=0;
  5. }


 
suivi de, planqué au fin fond d'une dll :
 

Code :
  1. class ID3D9VertexShader: public IVertexShader
  2. {
  3. public:
  4. virtual void setFloatConstant()
  5. {
  6. ..
  7. }
  8. }


 
En surface (dans l'exe), je n'ai donc que des IVertexShader *.
Soit le code suivant :
 
IVertexShader *r = createVertexShader();
 
comment recuperer (est ce seulement possible ?) l'adresse de la fonction qui va etre executé quand je ferais  
 

Code :
  1. r->setFloatConstant(..)


 
?
 
Ma magouille habituelle consiste a faire un truc du genre :
 
typedef void (Toto::*fVSPtr)(void);

Code :
  1. Toto a;
  2. fVSPtr ptr = a::laFonction();
  3. DWORD * lpAddr = (DWORD *)&ptr;


 
et donc dans *lpAddr j'ai l'addresse de la fonction membre souhaité (je vous le concede, la propreté n'est pas au rendez vous)
 
pb c que la visual rale
 

Code :
  1. error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'fVSPtr'


 
Bref, comment faire ?
 
(vivi j'en ai besoin, je sais ce que je fais)


Message édité par chrisbk le 02-09-2003 à 22:55:51
Reply

Marsh Posté le 01-09-2003 à 20:44:18   

Reply

Marsh Posté le 01-09-2003 à 20:56:54    

chrisbk a écrit :

vala, j'ai un objet genre :
 
(... snip ...)
 


 
Comme ça ?
 

Code :
  1. class IVertexShader
  2.   {
  3.     private:
  4.     virtual void _setFloatConstant()=0;
  5.     public:
  6.     void setFloatConstant() { _setFloatConstant(); }
  7.   }


 
:whistle:


Message édité par Kristoph le 01-09-2003 à 20:57:21
Reply

Marsh Posté le 01-09-2003 à 21:15:58    

Kristoph a écrit :


 
Comme ça ?
 

Code :
  1. class IVertexShader
  2.   {
  3.     private:
  4.     virtual void _setFloatConstant()=0;
  5.     public:
  6.     void setFloatConstant() { _setFloatConstant(); }
  7.   }


 
:whistle:


 
 
:D
 
en fait g deja plus ou moins un truc du genre et c justement ce double appel que je veux virer :D

Reply

Marsh Posté le 01-09-2003 à 21:25:16    

Code :
  1. #include <iostream>
  2. using namespace std;
  3. class Message
  4. {
  5. public:
  6.   virtual void greet() const =0;
  7.   virtual ~Message()
  8.   {}
  9. };
  10. class Hello
  11.   : public Message
  12. {
  13. public:
  14.   virtual void greet() const
  15.   {
  16.     cout << "Hello\n";
  17.   }
  18.   virtual ~Hello()
  19.   {}
  20. };
  21. class Bye
  22.   : public Message
  23. {
  24. public:
  25.   virtual void greet() const
  26.   {
  27.     cout << "Bye\n";
  28.   }
  29.   virtual ~Bye()
  30.   {}
  31. };
  32. int main()
  33. {
  34.   Message* m[2]=
  35.     {
  36.       new Hello,
  37.       new Bye
  38.     };
  39.   m[0]->greet();
  40.   m[1]->greet();
  41.   typedef void (Message::* MsgMemberFxPtr)() const ;
  42.   MsgMemberFxPtr f(&Message::greet);
  43.   (m[0]->*f)();
  44.   (m[1]->*f)();
  45.   delete m[0];
  46.   delete m[1];
  47. }


 
fais un petit tour dans la STL aussi, ça fournit de bon wrapper pour tout ça
 
edit: il me semble pas que le fais que ça soit virtuel ou pur, ou les deux, change quelque chose


Message édité par Taz le 01-09-2003 à 21:26:07
Reply

Marsh Posté le 01-09-2003 à 22:24:30    

j'ai pas des masses de succès  :(

Reply

Marsh Posté le 01-09-2003 à 22:41:35    

Taz a écrit :

j'ai pas des masses de succès  :(  


dsl j'etais pendu au tel, je regarde ton truc

Reply

Marsh Posté le 01-09-2003 à 22:51:26    

chrisbk a écrit :


dsl j'etais pendu au tel, je regarde ton truc

en fait, je vois ce que tu veux dire.. t'en as besoin pourquoi

Reply

Marsh Posté le 01-09-2003 à 22:56:06    

Taz a écrit :

en fait, je vois ce que tu veux dire.. t'en as besoin pourquoi

la vérité est que cette fonction n'a pas d'adresse si ce n'est dans la vtable. tout compilateur te jètera à la moindre convertion en quoi que soit. la seul astuce -> le hack C à coup d'union (je sais plus comment on dit genre piggy typing)
 

Code :
  1. typedef void (Message::* MsgMemberFxPtr)() const;
  2. union Hack
  3. {
  4.   MsgMemberFxPtr p;
  5.   void *v;
  6. };
  7.   Hack h;
  8.   h.p=0x00000000;
  9.   h.p=&Message::greet;
  10.   cout << h.v << endl;

Reply

Marsh Posté le 01-09-2003 à 22:57:22    

putain je sui qu'une grosse burne qui sait pas lire un message d'erreur :D
 
je vais me fouetter je reviens


Message édité par chrisbk le 01-09-2003 à 22:58:19
Reply

Marsh Posté le 01-09-2003 à 23:02:17    

Taz a écrit :

en fait, je vois ce que tu veux dire.. t'en as besoin pourquoi


 
 
j'ai fais un compilo ([:ciler]) et j'ai un binding ZGSL(le nom grotesque du truc)->C++
 
Bref
 
Jusque la j'ai un truc genre :
 
code ZGSL->appel fonction C++->appel fonction C++ finale
 
(cf truc Kristoph)
 
Bref, pour des raisons d'optimisations (oui j'en suis a compter les functions call) je veux supprimer le bout intermediaire
 
donc, je met le this dans ecx ([:aloy]) et tout ce que j'ai a faire c appeler la fonction virtuelle...puor ca j'ai besoin de son adresse. Vala !

Reply

Marsh Posté le 01-09-2003 à 23:02:17   

Reply

Marsh Posté le 01-09-2003 à 23:03:32    

Taz a écrit :

la vérité est que cette fonction n'a pas d'adresse si ce n'est dans la vtable. tout compilateur te jètera à la moindre convertion en quoi que soit.


 
J'etais parti de l'idée que le compilo a moyen de trouver cette adresse (au moins lors de l'appel), donc doit avoir moyen de la mettre dans une chtite variable

Reply

Marsh Posté le 01-09-2003 à 23:29:34    

Tiens, disassembly du truc :
 

Code :
  1. (m[0]->*f)();
  2. 004942C9 8B F4            mov         esi,esp  //s'en fout
  3. 004942CB 8B 4D F4         mov         ecx,dword ptr [m]  //this
  4. 004942CE FF 55 E8         call        dword ptr [f]


 
 
La derniere ligne est autement interessante !
Si on la suit on arrive sur :
 
 

Code :
  1. `vcall':
  2. 00494850 8B 01            mov         eax,dword ptr [ecx]
  3. 00494852 FF 20            jmp         dword ptr [eax]


(ecx etant this, [ecx] doit etre la vtable)
et un jmp plus loin...
 
 

Code :
  1. virtual void greet() const 
  2.     {
  3. 00494490 55               push        ebp 
  4. 00494491 8B EC            mov         ebp,esp


coucou [:dawa]
 
Conclusion : forcé le bourrinage  du pointeur gentillement refilé par le compilo


Message édité par chrisbk le 01-09-2003 à 23:29:47
Reply

Marsh Posté le 01-09-2003 à 23:42:10    

Et voila le travail !
 

Code :
  1. MsgMemberFxPtr f(&Message::greet);
  2. DWORD fPtr;
  3. DWORD thisPtr = (DWORD)m[1];
  4. _asm
  5. {
  6. mov eax,f;
  7. //   mov fPtr,eax;
  8. mov ecx,thisPtr;
  9. call eax;
  10. }


 
[:dawa]
 
Portabilité ? quelle portabilité ? [:ddr555]


Message édité par chrisbk le 01-09-2003 à 23:43:34
Reply

Marsh Posté le 01-09-2003 à 23:57:13    

Taz a écrit :

la vérité est que cette fonction n'a pas d'adresse si ce n'est dans la vtable. tout compilateur te jètera à la moindre convertion en quoi que soit. la seul astuce -> le hack C à coup d'union (je sais plus comment on dit genre piggy typing)
 

Code :
  1. typedef void (Message::* MsgMemberFxPtr)() const;
  2. union Hack
  3. {
  4.   MsgMemberFxPtr p;
  5.   void *v;
  6. };
  7.   Hack h;
  8.   h.p=0x00000000;
  9.   h.p=&Message::greet;
  10.   cout << h.v << endl;




 
 
tres elegant (j'avais skippé un peu vite, honte a moi)
 
vais la jouer comme ca tiens
 

Reply

Marsh Posté le 02-09-2003 à 00:08:41    

chrisbk a écrit :


 
 
tres elegant (j'avais skippé un peu vite, honte a moi)
 
vais la jouer comme ca tiens
 
 

on doit pas avoir la meme notion d'elegance [:wam]
 
bon en meme temps j'ai rien compris au code [:chacal_one333]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 02-09-2003 à 00:51:36    

the real moins moins a écrit :

on doit pas avoir la meme notion d'elegance [:wam]
 
bon en meme temps j'ai rien compris au code [:chacal_one333]


 
disons que ce je veux fair est de toute facon a ranger dans la categorie "cochonou", alors la notion d'elegance est toute relative

Reply

Marsh Posté le 02-09-2003 à 00:57:55    

:lol:


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 02-09-2003 à 09:27:45    

Reply

Marsh Posté le 02-09-2003 à 09:30:10    

Reply

Marsh Posté le 02-09-2003 à 09:30:43    

TTFN  :o

Reply

Marsh Posté le 02-09-2003 à 09:35:29    

Et une 2° méthode virtuelle qui renvoie l'adresse de celle souhaitée ? Ca serait + portable nan ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 02-09-2003 à 09:36:06    

Taz a écrit :

TTFN  :o  


 
heuh
ah ouais ? :O
Et bien HCNI sur TCZP :O
et je relance brique

Reply

Marsh Posté le 02-09-2003 à 09:37:25    

HelloWorld a écrit :

Et une 2° méthode virtuelle qui renvoie l'adresse de celle souhaitée ? Ca serait + portable nan ?


 
huh ?
comment elle recupere l'adresse, ta deuxieme fonction virtuelle ?
Nota, la solution de taz a l'air un minimum portable vu que ca marche sur mon VC et je doute fort qu'il ait jamais programmé dessus :D

Reply

Marsh Posté le 02-09-2003 à 09:39:02    

chrisbk a écrit :

Et bien HCNI sur TCZP :O

:heink:  :??:  
 
de toutes façons, il doit bien exister une putain d'implémentation sans vtable alors    [:spamafote]

Reply

Marsh Posté le 02-09-2003 à 09:44:16    


 
(rien cpris a ton TTtruc :D)
 

Taz a écrit :


de toutes façons, il doit bien exister une putain d'implémentation sans vtable alors    [:spamafote]  


 
Marche tres bien ta methode, j'assume pleinement le cote cochonou


Message édité par chrisbk le 02-09-2003 à 09:44:40
Reply

Marsh Posté le 02-09-2003 à 09:45:17    

c'est le TTFN que tu comprends pas?

Reply

Marsh Posté le 02-09-2003 à 09:45:55    

Taz a écrit :

c'est le TTFN que tu comprends pas?


 
ouaip, cette abreviation m'est inconnu

Reply

Marsh Posté le 02-09-2003 à 09:55:42    

chrisbk a écrit :


 
ouaip, cette abreviation m'est inconnu  

Quand Tigrou (Tigger) en a marre, il dit « ta ta for now » et s'en va en bondissant.
 
C'était donc de ma part un clin d'oeil pour dire: on arrete de dévier (meme si c'est moi qui est commencé  :sweat: )

Reply

Marsh Posté le 02-09-2003 à 10:05:46    

Taz a écrit :

Quand Tigrou (Tigger) en a marre, il dit « ta ta for now » et s'en va en bondissant.
 
C'était donc de ma part un clin d'oeil pour dire: on arrete de dévier (meme si c'est moi qui est commencé  :sweat: )


 
ah ok :D
 
Bah de toute facon  j'ai ma reponse, ca marche (enfin ca marchera quand ce compilo a la con arretera de croire que mon int est un float -ou je sais pas exactement ce qui lui passe par la tete)

Reply

Marsh Posté le 02-09-2003 à 10:19:12    

La classe qui concrétise une méthode virtuelle pure connaît l'adresse de cette méthode non (contrairement à la classe de base) ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 02-09-2003 à 10:30:47    

HelloWorld a écrit :

La classe qui concrétise une méthode virtuelle pure connaît l'adresse de cette méthode non (contrairement à la classe de base) ?


 
ben oui et non
 

Code :
  1. class A
  2. {
  3. virtual void truc()=0;
  4. virtual truc2 ()=0;
  5. }
  6. class B : public A
  7. {
  8. virtual void truc()
  9. {..
  10. }
  11. virtual void truc2()
  12. {
  13. truc()
  14. }
  15. }
  16. class C : public B
  17. {
  18. virtual void truc()
  19. {..
  20. }
  21. }


 
 
truc2 de B ne connait pas forcement l'dresse de truc
 
 

Reply

Marsh Posté le 02-09-2003 à 10:51:34    

pour formaliser un peu le Hack, si certains qui passe ici veulent faire mu-muse
 

Code :
  1. #include <iostream>
  2. #include <iomanip>
  3. template<typename T>
  4. struct Hack
  5. {
  6.   typedef T Type;
  7.   static const size_t Size;
  8.  
  9.   union
  10.   {
  11.     T d;
  12.     unsigned char raw[sizeof(T)];
  13.   };
  14. };
  15. template<typename T>
  16. const size_t Hack<T>::Size(sizeof(T));
  17. template<typename T>
  18. ostream & operator<<(ostream &os, const Hack<T> &h)
  19. {
  20.   os << "0x ";
  21.   for(size_t i=0; i<h.Size; ++i)
  22.     {
  23.       if(i!=(h.Size-1))
  24. {
  25.   cout << ' ';
  26. }
  27.     }
  28.   os << '\t' << h.Size << " byte" << (h.Size>1 ? "s" : "" );
  29.   return os;
  30. }


 
 
edit: l'affichage est pourri mais me convient


Message édité par Taz le 02-09-2003 à 11:06:11
Reply

Marsh Posté le 02-09-2003 à 11:22:55    

Mais si tu désignes tes méthodes ainsi : B::truc, C::truc, ça va pas ?
 

Code :
  1. class B : public A
  2. {
  3. virtual void truc()
  4. {..
  5. }
  6. virtual void get_truc()
  7. {
  8.     return B::truc;
  9. }
  10. }


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 02-09-2003 à 22:41:08    

tiens ouais pas essayé
 
Anyway les enfants, je sais pas si c'est specifique a visu mais l'appel de fonction virtuelles a la main c'est un bordel sans nom je suis pas sur de tout bien comprendre [:meganne]

Reply

Marsh Posté le 02-09-2003 à 22:56:20    

(modif : cf premier post)

Reply

Marsh Posté le 02-09-2003 à 22:57:36    

c'est quoi une fonction virtuelle pure [:autobot]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 02-09-2003 à 22:58:30    

the real moins moins a écrit :

c'est quoi une fonction virtuelle pure [:autobot]


 
en java ca serait une fonction abstract

Reply

Marsh Posté le 02-09-2003 à 23:08:46    

mais qu'est-ce que tu veux faire avec son adresse alors :??:


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 02-09-2003 à 23:14:20    

the real moins moins a écrit :

mais qu'est-ce que tu veux faire avec son adresse alors :??:
 


 
le con :D
Appeler depuis mon langage a moi (qui est compilé en asm) des fonctions C++. Deshalb j'ai besion de l'adresse de ladite fonction


Message édité par chrisbk le 02-09-2003 à 23:15:03
Reply

Marsh Posté le 02-09-2003 à 23:37:56    

putain tout monde compilé est foireux a cause d'un push ecx, autrement un malheureux octet :cry:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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