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 :
- mov edi,truc
- ...
- toto(20,30)
- ...
|
Le tout etant de faire ce setup de facon transparente pour l'utilisateur. Apres quelques bricolages, je suis arrivé a ca :
Code :
- template <class R,class Param1>
- class Exec
- {
- R operator(Param1 a)
- {
- typedef R (__stdcall *tagada)(Param1);
- tagada r = (tagada) code;
- ...
- returnType tmp = r(a);
- ...
- return tmp;
- }
- }
|
Bon, ca ca marche pour une fonction prenant un seul argument. Si y'en faut plus, alors ca ne va plus. Re-bricolage :
Code :
- class Lock
- {
- private:
- Lock(){};
- };
- template <class returnType,class TypeParam1=Lock,class TypeParam2=Lock,class TypeParam3=Lock,class TypeParam4=Lock>
- class Exec
- {
- public:
- returnType operator () (TypeParam1 a)
- {
- typedef returnType (__stdcall *tagada)(TypeParam1);
- tagada r = (tagada) code;
- returnType tmp = r(a);
- return tmp;
- }
- returnType operator () (TypeParam1 a,TypeParam2 b)
- {
- typedef returnType (__stdcall *tagada)(TypeParam1,TypeParam2);
- tagada r = (tagada) code;
- returnType tmp = r(a,b);
- return tmp;
- }
-
- ...
- };
|
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 :
- exec<int,float> toto = .....;
- 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
(et si la chose ci dessus vous a fait frémir d'horreur, je suis ouvert a toute amélioration )
thks !