J'ai des fonctions que je souhaite appeler en fonction de certaines entrées. Chaque fonction a un nombre différent d'arguments. En d'autres termes,Appel de fonctions cdecl ayant un nombre différent d'arguments
if (strcmp(str, "funcA") == 0) funcA(a, b, c);
else if (strcmp(str, "funcB") == 0) funcB(d);
else if (strcmp(str, "funcC") == 0) funcC(f, g);
Ceci est un peu volumineux et difficile à maintenir. Idéalement, ce sont des fonctions variadiques (par exemple, style printf) et peuvent utiliser des varargs. Mais ils ne le sont pas. Donc en exploitant la convention d'appel de cdecl, je bourre la pile via une structure complète de paramètres. Je me demande s'il y a une meilleure façon de le faire. Notez que ceci est strictement pour l'interne (par exemple, des outils simples, des tests unitaires, etc.) et ne sera pas utilisé pour tout code de production qui pourrait être soumis à des attaques malveillantes.
Exemple:
#include <stdio.h>
typedef struct __params
{
unsigned char* a;
unsigned char* b;
unsigned char* c;
} params;
int funcA(int a, int b)
{
printf("a = %d, b = %d\n", a, b);
return a;
}
int funcB(int a, int b, const char* c)
{
printf("a = %d, b = %d, c = %s\n", a, b, c);
return b;
}
int funcC(int* a)
{
printf("a = %d\n", *a);
*a *= 2;
return 0;
}
typedef int (*f)(params);
int main(int argc, char**argv)
{
int val;
int tmp;
params myParams;
f myFuncA = (f)funcA;
f myFuncB = (f)funcB;
f myFuncC = (f)funcC;
myParams.a = (unsigned char*)100;
myParams.b = (unsigned char*)200;
val = myFuncA(myParams);
printf("val = %d\n", val);
myParams.c = (unsigned char*)"This is a test";
val = myFuncB(myParams);
printf("val = %d\n", val);
tmp = 300;
myParams.a = (unsigned char*)&tmp;
val = myFuncC(myParams);
printf("a = %d, val = %d\n", tmp, val);
return 0;
}
Sortie:
gcc -o func func.c
./func
a = 100, b = 200
val = 100
a = 100, b = 200, c = This is a test
val = 200
a = 300
a = 600, val = 0
Quelle est votre question? –
Je peux vous donner une réponse relativement sûre pour C++, mais pour C sauf si vous appelez des fonctions variadiques, vous ne pouvez pas garantir que chaque paramètre aura la même taille sur la pile. – MSN
Les paramètres de la pile ne sont-ils pas cast/sauvegardés comme alignés sur la mémoire (par exemple, 32 bits, 64 bits) et sont donc de la même taille? – KlaxSmashing