Template / Pointeur de fonction

Template / Pointeur de fonction - C++ - Programmation

Marsh Posté le 15-01-2003 à 00:09:42    

Bon, les soirées d'hiver étant longues et vu qu'il faut bien les occuper, je me suis fait un petit compilo. Le bougre commence a atteindre l'age de maturité, et il me sort du code asm avec le sourrire aux lèvres. Ledit code ASM respectant les normes __stcall de passage de paramêtres/retour de fonction, il est envisageable d'appeler depuis le C++ des fonctions compilées en runtime grace au compilo susnommé, par le truchement de pointeur de fonction. (simple et agréable) Et la se trouve le noeud du problème.
 
un appel de fonction du code compilé ne se limite pas a un push des parametres suivi d'un call. Il y a un petit setup a faire avant de pouvoir executer le code (mise d'une valeur sur EDI, entre autres conneries). Ce qui fait qu'un truc genre :
 
toto(20,30)
 
devrait etre (idéalement) transformé par le compilo (VC, pas le mien), en :
 

Code :
  1. mov edi,truc
  2. ...
  3. toto(20,30)
  4. ...


 
Le tout etant de faire ce setup de facon transparente pour l'utilisateur. Apres quelques bricolages, je suis arrivé a ca :
 

Code :
  1. template <class R,class Param1>
  2. class Exec
  3. {
  4.     R operator(Param1 a)
  5.     {
  6.         typedef  R (__stdcall *tagada)(Param1);
  7.         tagada r = (tagada) code;
  8.         ...
  9.         returnType tmp = r(a);
  10.         ...
  11.         return tmp;
  12.     }
  13. }


 
Bon, ca ca marche pour une fonction prenant un seul argument. Si y'en faut plus, alors ca ne va plus. Re-bricolage :
 

Code :
  1. class Lock
  2. {
  3. private:
  4.     Lock(){};
  5. };
  6. template <class returnType,class TypeParam1=Lock,class TypeParam2=Lock,class TypeParam3=Lock,class TypeParam4=Lock>
  7. class Exec
  8. {
  9. public:
  10.     returnType operator () (TypeParam1 a)
  11.     {
  12.         typedef  returnType  (__stdcall *tagada)(TypeParam1);
  13.         tagada r = (tagada) code;
  14.         returnType tmp = r(a);
  15.         return tmp;
  16.     }
  17.     returnType operator () (TypeParam1 a,TypeParam2 b)
  18.     {
  19.         typedef  returnType  (__stdcall *tagada)(TypeParam1,TypeParam2);
  20.         tagada r = (tagada) code;
  21.         returnType tmp = r(a,b);
  22.         return tmp;
  23.     }
  24.  
  25.     ...
  26. };


 
Les fonctions avec plus de 4 parametres se faisant plutot rare (surtout dans mon langage), ca devrait aller. (au pire, on rajoute une peletée de template au début, deux louches de surcharges de fonctions, et zou).  
 
La supairbe classe Lock sert a empecher un appel de fonction avec plus d'argument qu'initialement prévu. Genre :
 

Code :
  1. exec<int,float> toto = .....;
  2. toto(20,30,10,20); // la ca coincera a la compil. Vu que le constructeur de Lock est en private, on est peinard, pas de blagues possibles


 
Mais ca ne protege pas contre l'appel avec moins de parametres qu'initialement prévu. Et c'est la que je fais appel a vous. Est ce que qqun voit comment faire cette protection (a la compilation du code C++), de facon (plus ou moins) propre ?
 
suggestions appréciées :D (et si la chose ci dessus vous a fait frémir d'horreur, je suis ouvert a toute amélioration )
 
 
thks !

Reply

Marsh Posté le 15-01-2003 à 00:09:42   

Reply

Marsh Posté le 15-01-2003 à 00:25:22    

Cree 5 templates differents, chacunes prenant un nombre de paramètres different et ne deffinissant qu'un seul operateur ().
 
Ne fait pas appel aux paramètres de template par defaut.

Reply

Marsh Posté le 15-01-2003 à 03:19:03    

Edit: grillé.
 
Les patrons C++ permettent bien de choisir entre plusieurs codes.
Pourquoi pas tout simplement faire autant de patrons exec que de nombre d'arguments possibles ?

Code :
  1. template <class returnType, class TypeParam1>
  2. class Exec{
  3. public:
  4. returnType operator () (TypeParam1 a);
  5. };
  6. template <class returnType, class TypeParam1, class TypeParam2>
  7. class Exec{
  8. public:
  9. returnType operator () (TypeParam1 a, TypeParam2 b);
  10. };
  11. template <class returnType, class TypeParam1, class TypeParam2, class TypeParam3>
  12. class Exec{
  13. public:
  14. returnType operator () (TypeParam1 a, TypeParam2 b, TypeParam3 c);
  15. };
  16. template <class returnType, class TypeParam1, class TypeParam2, class TypeParam3, class TypeParam4>
  17. class Exec{
  18. public:
  19. returnType operator () (TypeParam1 a, TypeParam2 b, TypeParam3 c, TypeParam4 c):
  20. };


 
Pas de valeur par défaut, pas d'embrouille...


Message édité par Musaran le 15-01-2003 à 03:20:06

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 15-01-2003 à 08:06:15    

thks, je savais pas qu'il etait possible de faire des classes possedant un nom identique mais un nb de template differents.
Comme ca c peinard

Reply

Sujets relatifs:

Leave a Replay

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