2

I have a function void startScanner(...) taking two function pointer as arguments: userType *vConfig(void) and void * vCallback(void). In this function i would like to create a thread and call vCallback() function in the function thread created. So i decided to pass vCallback as args to pthreadcreate. The code of startScanner function :

void startScanner(tUsrStatus (*vConfig)(), void* (vCallback)()){

    if(pthread_create(&scannerThread, NULL, scannerThreadFunc, vCallback))
    {
        printf("Thread creation fails!\n");
    }
}

The scannerTread function:

static void *scannerThreadFunc(void *arg()){

    void *funcptr(void) = arg;

    while(1)
    {
        funcptr();
    }
    pthread_exit(NULL);
}

I get the following error:

error: function ‘funcptr’ is initialized like a variable
error: nested function ‘funcptr’ declared but never defined

How can i fix this?

1
  • 1
    Do you see any difference between your second argument in the first snippet and you funcptr decl in your second snippet. Hmm.... (hint: recheck your syntax of arg too). I'm nearly certain all of those cases should be void *(*varname)(void). That is, if you are passing an address of a function that (a) returns void*, and (b) accepts no arguments. Commented Apr 23, 2018 at 8:54

1 Answer 1

4

Syntax errors aside (*) , it's impossible in standard C to pass a function pointer in a void *. There's a fundamental difference between pointers to functions and pointers to data, they can't be converted into each other. This is because there might be platforms where function and data pointers would differ even in size, or refer to different address spaces, or whatever.

But of course, there's a simple way to achieve what you want: Put your function pointer inside a struct and pass a pointer to that.

typedef (*callback)(void);

typedef struct threadargs
{
    callback cb;
} threadargs;

void mycallback(void)
{
    // ...
}

void *threadfunc(void *arg)
{
    threadargs *ta = arg;

    // call your callback:
    ta->cb();

    return ta; // or: return 0, or some pthread_exit(), ...
}

int main(void)
{
    pthread_t thread;
    threadargs ta = { mycallback };
    pthread_create(&thread, 0, threadfunc, &ta);

    // make sure "ta" lives for as long as the thread executes,
    // here just wait until it exits:
    pthread_join(&thread, 0);
}

add error checking etc.


(*) as for the concrete error you're getting, a function pointer needs parantheses around the identifier, so instead of

void *funcptr(void) = arg;

you'd have to write

void (*funcptr)(void) = arg;

To facilitate the usage of function pointers, it's common to typedef them, as seen in my example above. Anyways, as explained above, this wouldn't solve your problem here.

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

7 Comments

No need to create a special struct, it's enough to pass a pointer to a pointer.
@n.m. maybe I misread the question, I was under the impression that the ultimate goal was to pass two pointers. Anyways, a struct doesn't hurt and is the generic solution.
Thanks Felix, i write it in this way. there is no longer compilation issue but i have a SIGSEGV sigmentation fault when it try to execute the callback function "ta -> cb()". Here is my code: pastebin.com/LDistHye
@julesconté see my comment "make sure "ta" lives for as long as the thread executes". You don't in your code. One option would be to declare it static, it depends on your usecase.
@FelixPalmen, it works with static déclaration. But is there the best way to implement callback function in the function thread?
|

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.