knolz
knolz

Reputation: 191

How to use macro for calling function?

I want to call function according to func_name string. My code is here below:

#define MAKE_FUNCNAME func_name##hello

void call_func(void* (*func)(void))
{
    func();
}

void *print_hello(void)
{
    printf("print_hello called\n");
}

int main(void)
{
    char func_name[30] = "print_";

    call_func(MAKE_FUNCNAME);
    return 0;
}

But this code doesn't work. I want code to work like call_func(print_hello). But preprocessor treated my code like call_func("print_hello"). How to use macro in C to make my exception? Or is it not possible using C?

Upvotes: 2

Views: 1728

Answers (3)

OznOg
OznOg

Reputation: 4732

Maybe you could have a look to dlsym().

Not sure I really understand the question, but if you want to "build" the function name at runtime and then call the corresponding function, it should be possible with dlsym()

/* compile with: gcc example.c -ldl -rdynamic */
#include <dlfcn.h>
#include <stdio.h>

int print_hello(void)
{
    return printf("hello\n");
}

int main(int argc, char *argv[])
{
    const char *name = "print_hello";
    if (argc == 42) 
        print_hello(); /* for compiler not to remove print_hello at
                        * compile time optimisation in this example*/
    void *handle = dlopen(NULL /* self */, RTLD_NOW);
    int (*f)(void) = dlsym(handle, name);
    f();
    return dlclose(handle);
}

Upvotes: 1

wefwefa3
wefwefa3

Reputation: 4036

Then problem with your code is that the value of func_name is only known at run-time.

You can however to it like this:

#define MAKE_FUNCNAME(FUNCNAME) FUNCNAME##hello

void call_func(void* (*func)(void))
{
    func();
}

void *print_hello(void)
{
    printf("print_hello called\n");
}

int main(void)
{
    call_func(MAKE_FUNCNAME(print_));
    return 0;
}

But it is not possible to use a string value within macro parameters like in your code snippet.

If you want to get call functions with their names using string values you can use a table to store function pointer with function names like this:

struct {
    const char *name;
    void (*ptr)(void);
};

You can use an array of this structure to find out the function pointer at run-time using a string value. This is the most common solution to using run-time strings to call functions using their names.

Upvotes: 4

Harald
Harald

Reputation: 3180

You can't do that. The value of func_name is known at run-time (even though it is a const char *), while you want to determine what to call at precompile-time. You should turn your cpp macro into something different (such as an if/switch statement or using an indirection).

Upvotes: 2

Related Questions