Calling cdecl Functions That Have Different Number of Arguments

Posted by KlaxSmashing on Stack Overflow See other posts from Stack Overflow or by KlaxSmashing
Published on 2010-03-11T18:54:59Z Indexed on 2010/03/11 18:59 UTC
Read the original article Hit count: 232

I have functions that I wish to call based on some input. Each function has different number of arguments. In other words,

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

This is a bit bulky and hard to maintain. Ideally, these are variadic functions (e.g., printf-style) and can use varargs. But they are not. So exploiting the cdecl calling convention, I am stuffing the stack via a struct full of parameters. I'm wondering if there's a better way to do it. Note that this is strictly for in-house (e.g., simple tools, unit tests, etc.) and will not be used for any production code that might be subjected to malicious attacks.

Example:

#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;
}

Output:

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

© Stack Overflow or respective owner

Related posts about c

    Related posts about variadic-functions