Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1463 connectés 

  FORUM HardWare.fr
  Programmation
  C++

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

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

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

n°504423
chrisbk
-
Posté le 01-09-2003 à 20:44:18  profilanswer
 

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
mood
Publicité
Posté le 01-09-2003 à 20:44:18  profilanswer
 

n°504427
Kristoph
Posté le 01-09-2003 à 20:56:54  profilanswer
 

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
n°504441
chrisbk
-
Posté le 01-09-2003 à 21:15:58  profilanswer
 

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

n°504446
Taz
bisounours-codeur
Posté le 01-09-2003 à 21:25:16  profilanswer
 

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
n°504520
Taz
bisounours-codeur
Posté le 01-09-2003 à 22:24:30  profilanswer
 

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

n°504534
chrisbk
-
Posté le 01-09-2003 à 22:41:35  profilanswer
 

Taz a écrit :

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


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

n°504539
Taz
bisounours-codeur
Posté le 01-09-2003 à 22:51:26  profilanswer
 

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

n°504543
Taz
bisounours-codeur
Posté le 01-09-2003 à 22:56:06  profilanswer
 

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;

n°504544
chrisbk
-
Posté le 01-09-2003 à 22:57:22  profilanswer
 

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
n°504548
chrisbk
-
Posté le 01-09-2003 à 23:02:17  profilanswer
 

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 !

mood
Publicité
Posté le 01-09-2003 à 23:02:17  profilanswer
 

n°504550
chrisbk
-
Posté le 01-09-2003 à 23:03:32  profilanswer
 

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

n°504565
chrisbk
-
Posté le 01-09-2003 à 23:29:34  profilanswer
 

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
n°504572
chrisbk
-
Posté le 01-09-2003 à 23:42:10  profilanswer
 

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
n°504579
chrisbk
-
Posté le 01-09-2003 à 23:57:13  profilanswer
 

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
 

n°504582
the real m​oins moins
Posté le 02-09-2003 à 00:08:41  profilanswer
 

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 ?
n°504603
chrisbk
-
Posté le 02-09-2003 à 00:51:36  profilanswer
 

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

n°504607
the real m​oins moins
Posté le 02-09-2003 à 00:57:55  profilanswer
 

:lol:


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
n°504697
Taz
bisounours-codeur
Posté le 02-09-2003 à 09:27:45  profilanswer
 
n°504699
chrisbk
-
Posté le 02-09-2003 à 09:30:10  profilanswer
 
n°504700
Taz
bisounours-codeur
Posté le 02-09-2003 à 09:30:43  profilanswer
 

TTFN  :o

n°504705
HelloWorld
Salut tout le monde!
Posté le 02-09-2003 à 09:35:29  profilanswer
 

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
n°504706
chrisbk
-
Posté le 02-09-2003 à 09:36:06  profilanswer
 

Taz a écrit :

TTFN  :o  


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

n°504708
chrisbk
-
Posté le 02-09-2003 à 09:37:25  profilanswer
 

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

n°504710
Taz
bisounours-codeur
Posté le 02-09-2003 à 09:39:02  profilanswer
 

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]

n°504717
chrisbk
-
Posté le 02-09-2003 à 09:44:16  profilanswer
 


 
(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
n°504719
Taz
bisounours-codeur
Posté le 02-09-2003 à 09:45:17  profilanswer
 

c'est le TTFN que tu comprends pas?

n°504721
chrisbk
-
Posté le 02-09-2003 à 09:45:55  profilanswer
 

Taz a écrit :

c'est le TTFN que tu comprends pas?


 
ouaip, cette abreviation m'est inconnu

n°504733
Taz
bisounours-codeur
Posté le 02-09-2003 à 09:55:42  profilanswer
 

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: )

n°504749
chrisbk
-
Posté le 02-09-2003 à 10:05:46  profilanswer
 

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)

n°504762
HelloWorld
Salut tout le monde!
Posté le 02-09-2003 à 10:19:12  profilanswer
 

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
n°504774
chrisbk
-
Posté le 02-09-2003 à 10:30:47  profilanswer
 

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
 
 

n°504819
Taz
bisounours-codeur
Posté le 02-09-2003 à 10:51:34  profilanswer
 

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
n°504865
HelloWorld
Salut tout le monde!
Posté le 02-09-2003 à 11:22:55  profilanswer
 

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
n°505844
chrisbk
-
Posté le 02-09-2003 à 22:41:08  profilanswer
 

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]

n°505867
chrisbk
-
Posté le 02-09-2003 à 22:56:20  profilanswer
 

(modif : cf premier post)

n°505869
the real m​oins moins
Posté le 02-09-2003 à 22:57:36  profilanswer
 

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


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
n°505871
chrisbk
-
Posté le 02-09-2003 à 22:58:30  profilanswer
 

the real moins moins a écrit :

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


 
en java ca serait une fonction abstract

n°505881
the real m​oins moins
Posté le 02-09-2003 à 23:08:46  profilanswer
 

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


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
n°505888
chrisbk
-
Posté le 02-09-2003 à 23:14:20  profilanswer
 

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
n°505912
chrisbk
-
Posté le 02-09-2003 à 23:37:56  profilanswer
 

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

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

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

 

Sujets relatifs
comment est programmée la fonction 'rafraichir' de l'explorateur ?fonction qui redirige vers une autre page ?
[visualc++] recuperer nom du CPU ?!SQL supprimer des données d'une table en fonction d'une autre
[File_exists] equivalent de cette fonction appliquable en rézo ?[Access VB] Page Web Recuperer la valeur d'un champ?
[php] Fonction INCLUDE chez Online.fr[Python] Fonction d'attente
[php] Recuperer l'extension d'un fichier pour l'afficher[jsp] comment récupérer la valeur d'un champ ?
Plus de sujets relatifs à : [C++] Recuperer l'adresse d'une fonction virtuelle pure [modified]


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR