Trouble with pointer to a function

T

Thomas Barth

Hi,
I dont understand the third argument of this function. This function
expect the address of a function, but what does "void *(*funktion)(void
*)," mean? I am confused by so many "wildcards" :)

int pthread_create( pthread_t *thread,
const pthread_attr_t *attribute,
void *(*funktion)(void *),
void *argumente );


When invoking the pthread_create function I get an error at compile time.

[...]
void BlockOp::start() {
if(pthread_create(&pth, NULL, &BlockOp::process, cBuffer) != 0) {
...
}
}

void BlockOp::process() {
int i;
for (i = 0; i < iLimit; ++i) {
...
}
pthread_exit((void *) val++);
}
[...]

error: cannot convert `void (BlockOp::*)()' to `void*(*)(void*)' for
argument `3' to `int pthread_create(pthread_t*, const pthread_attr_t*,
void*(*)(void*), void*)' BlockOp.cpp blockop line 17

Any idea how to clear it up?

Regards,
T h o m a s B
 
B

ben

Thomas said:
Hi,
I dont understand the third argument of this function. This function
expect the address of a function, but what does "void *(*funktion)(void
*)," mean? I am confused by so many "wildcards" :)

int pthread_create( pthread_t *thread,
const pthread_attr_t *attribute,
void *(*funktion)(void *),
void *argumente );

A pointer to function can be declared as ReturnT (*PtrToFuncT)(ArgT1,
ArgT2...). So void* (*function)(void*) means "function" is a
pointer-to-a function which takes a pointer-to-void as an parameter and
returns a pointer-to-void.

So say you have a function called hello:

void* hello(void*);

Then you can assign function with hello:

void* (*function)(void*);
function = &hello;
When invoking the pthread_create function I get an error at compile time.

[...]
void BlockOp::start() {
if(pthread_create(&pth, NULL, &BlockOp::process, cBuffer) != 0) {
...
}
}

void BlockOp::process() {
int i;
for (i = 0; i < iLimit; ++i) {
...
}
pthread_exit((void *) val++);
}
[...]

error: cannot convert `void (BlockOp::*)()' to `void*(*)(void*)' for
argument `3' to `int pthread_create(pthread_t*, const pthread_attr_t*,
void*(*)(void*), void*)' BlockOp.cpp blockop line 17


From the compiler error we know that BlockOp::process takes no argument
and returns nothing at all, assuming it is a static member function.

In otherwords, Block::process, assumed static, is of type void(void).
Note that pthread_create requires a pointer to void*(void*) and you
can't therefore pass Block::process.

Any idea how to clear it up?

Regards,
T h o m a s B

If you really don't care about the void* argument you can wrap up
Block::process like so:

void* thread_entry(void* trivial)
{
Block::process();
}

Ben
 
B

ben

Thomas said:
> Hi,
> I dont understand the third argument of this function. This function
expect the address of a function, but what does "void *(*funktion)(void
*)," mean? I am confused by so many "wildcards" :)
>
> int pthread_create( pthread_t *thread,
> const pthread_attr_t *attribute,
> void *(*funktion)(void *),
> void *argumente );


A pointer to function can be declared as ReturnT (*PtrToFuncT)(ArgT1,
ArgT2...). So void* (*function)(void*) means "function" is a
pointer-to-a function which takes a pointer-to-void as an parameter and
returns a pointer-to-void.

So say you have a function called hello:

void* hello(void*);

Then you can assign function with hello:

void* (*function)(void*);
function = &hello;
>
>
> When invoking the pthread_create function I get an error at compile time.
>
> [...]
> void BlockOp::start() {
> if(pthread_create(&pth, NULL, &BlockOp::process, cBuffer) != 0) {
> ...
> }
> }
>
> void BlockOp::process() {
> int i;
> for (i = 0; i < iLimit; ++i) {
> ...
> }
> pthread_exit((void *) val++);
> }
> [...]
>
> error: cannot convert `void (BlockOp::*)()' to `void*(*)(void*)' for
argument `3' to `int pthread_create(pthread_t*, const pthread_attr_t*,
void*(*)(void*), void*)' BlockOp.cpp blockop line 17


From the compiler error we know that BlockOp::process takes no argument
and returns nothing at all, assuming it is a static member function.

In otherwords, Block::process, assumed static, is of type void(void).
Note that pthread_create requires a pointer to void*(void*) and you
can't therefore pass Block::process.

> Any idea how to clear it up?
>
> Regards,
> T h o m a s B


If you really don't care about the void* argument you can wrap up
Block::process like so:

void* thread_entry(void* trivial)
{
Block::process();
}

Ben
 
N

n2xssvv g02gfr12930

Thomas said:
Hi,
I dont understand the third argument of this function. This function
expect the address of a function, but what does "void *(*funktion)(void
*)," mean? I am confused by so many "wildcards" :)

int pthread_create( pthread_t *thread,
const pthread_attr_t *attribute,
void *(*funktion)(void *),
void *argumente );


When invoking the pthread_create function I get an error at compile time.

[...]
void BlockOp::start() {
if(pthread_create(&pth, NULL, &BlockOp::process, cBuffer) != 0) {
...
}
}

void BlockOp::process() {
int i;
for (i = 0; i < iLimit; ++i) {
...
}
pthread_exit((void *) val++);
}
[...]

error: cannot convert `void (BlockOp::*)()' to `void*(*)(void*)' for
argument `3' to `int pthread_create(pthread_t*, const pthread_attr_t*,
void*(*)(void*), void*)' BlockOp.cpp blockop line 17

Any idea how to clear it up?

Regards,
T h o m a s B

The function required by pthread_create() is of the form

void *thread_fnc(void *Data)

You tried to pass a pointer to a non static member function
Create a static member function and pass a pointer to an array
of pointers for the object and required data that can then be
used to call the required member function. Hopefully the sample
code below will point you in the right direction.

class Example
{
public:
static void *thread_fnc(void *pData);

private:
void My_Fnc(char *pBuffer);
};

void *Example::thread_fnc(void *pData)
{
void **p = reinterpret_cast<void **>(pData);
Example *pObj = reinterpret_cast<Example *>(p[0])
char *pBuffer = reinterpret_cast<char *>(p[1])
pObj->My_Fnc(pBuffer);
}


void Some_fnc(void)
{
pthread_t Thr;
.
.
.
char cBuffer[20];
void *pData[2] = { &Obj,cBuffer };
pthread_create(&Thr, NULL, &Example::thread_fnc, &pData);
.
.
return ptr;
}

Of course you could always use a temporary object rather
than the array of void pointers, (probably a cleaner solution).

JFJB
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top