pchemaly
pchemaly

Reputation: 21

How to pass "a pointer to a function with parameters" to another function

I have the following system function:

int sock_yield( void *s, void (*fn)() );

to which I need to pass a function that takes 2 parameters:

void reset(char buf,udp_Socket sock) {

    if (-1 == udp_recv(&sock, &buf, sizeof(buf)));

    if(buf=='R')
    {

        printf("\nReceived-> %c",buf);

        forceSoftReset();

        forceWatchdogTimeout();

    }

}

When calling sock_yield function I can only pass it the name of the function without its parameter: sock_yield(sock, reset)

How to specify the parameters of reset to be passed to sock_yield?

Upvotes: 2

Views: 76

Answers (2)

Serge Ballesta
Serge Ballesta

Reputation: 149185

You cannot. C only knows raw pointer to functions. You can then give all the required parameters when you use the pointer. Example:

int double(int i) {
    return 2*1;
}

int exec_op(int param, int (*op)()) {
   return op(param);
}

This works because in C a void parameter list means that the function can accept any parameters.

If in your use case sock_yield calls the function without parameters, the only option is to use a wrapper using global parameters:

char Buf;
udp_Socket Sock;

void reset_wrapper(void) {
    reset(Buf, Sock);
}

and later use it that way:

    Buf = buf;
    Sock = sock;
    sock_yield(s, &reset_wrapper);

Upvotes: 1

Lundin
Lundin

Reputation: 215360

You cannot do this. Converting between different function types is strictly speaking undefined behavior, although some compilers have non-standard extensions that allow it at some extent.

In addition, void (*fn)() means a function taking any parameters, which is obsolete style C and shouldn't be used.

So the sock_yield function must be rewritten. If it was meant to take a callback function as parameter, it was badly written from the start. It should take function pointers of one specific, specified format. For example:

typedef void sock_callback_t (char buf, udp_socket* sock);

int sock_yield(void* s, sock_callback_t* fn); 

Alterntatively you could write some hack where you convert between function pointers and uintptr_t, but it is a worse solution that should only be used if you are stuck with a badly written API.

Upvotes: 5

Related Questions