2

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?

2

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.