Minh Tran
Minh Tran

Reputation: 510

How to assign a function to a function pointer that takes argument of type void*?

I'm using a library provided by my professor for a class assignment so I can't reveal too much of my code. Here's part of the API:

typedef void (*thread_startfunc_t) (void*); 
int thread_libinit(thread_startfunc_t func, void *arg);
int thread_create(thread_startfunc_t func, void *arg);

 thread_libinit initializes the thread library.  A user program should call
 thread_libinit exactly once (before calling any other thread functions).
 thread_libinit creates and runs the first thread.  This first thread is
 initialized to call the function pointed to by func with the single
 argument arg.  Note that a successful call to thread_libinit will not
 return to the calling function.  Instead, control transfers to func, and
 the function that calls thread_libinit will never execute again.

 thread_create is used to create a new thread.  When the newly created
 thread starts, it will call the function pointed to by func and pass it the
 single argument arg.

To test I wrote the following code:

void pHello(int i)
{
   cout << "Hello from thread " << i << endl;
}

... [In Main] ...

typedef void (*thread_startfunc_t) (void* i); 
thread_startfunc_t pSalute = & pHello; //Does not compile

thread_libinit(pSalute,1); 

I receive the error:

In function `int main(int, char**)`: 
error: invalid conversion from `void (*) (int)' to `thread_startfunc_t{aka void(*) (void*)}' [-fpermissive]

I thought a void pointer variable can point to any variable. So why can't it point to the int of the function pHello? How do I assign a function to the function pointer?

Upvotes: 1

Views: 1211

Answers (2)

Christian Hackl
Christian Hackl

Reputation: 27518

I thought a void pointer variable can point to any variable. So why can't it point to the int of the function pHello?

Because the statement is not correct. In C++, you must use casts for this. This is one of the big differences between C++ and C. See also Difference between void pointers in C and C++

You can test this. Compile your code as C, remove C++ features like <iostream>, and it should work as intended.

How do I assign a function to the function pointer?

Change the signature of pHello to:

void pHello(void*)

Inside the function, you must use casts to obtain the value of the pointee.

Also, when you call thread_libinit, the second argument must be the address of an int object which lives until the function returns.


Of course, none of this is very nice or modern C++. Your professor's API should instead make use of std::function.

Upvotes: 1

davidhigh
davidhigh

Reputation: 15468

A function pointer with a specific signature (given as return type plus variable types) can only point to functions having the same signature.

In your case, where it seems you can't change the function pointer type, you can change your function pHello according to

void pHello(void* i)
{
   std::cout << "Hello from thread " << *static_cast<int*>(i) << std::endl;
}

typedef void (*thread_startfunc_t) (void*);

int main()
{
    thread_startfunc_t f = pHello;

    //or point to a non-capturing lambda:
    thread_startfunc_t f2 = [](void *) { std::cout<<"hi"<<std::endl; };
}

This is however not really nice C++ code.

Upvotes: 2

Related Questions