简体   繁体   中英

Invalid conversion from 'void*' to 'void (*)(..)'

I have error

invalid conversion from 'void*' to 'void ( )(void , u_int8_t*, u_int8_t*, u_int16_t, void*) {aka void ( )(void , unsigned char*, unsigned char*, short unsigned int, void*)}' [-fpermissive]

void m_callback_friendrequest(Messenger *m, void (*function)(Messenger *m, u_int8_t *, u_int8_t *, u_int16_t, void *), void *userdata)
{
    void (*handle_friendrequest)(void *, u_int8_t *, u_int8_t *, u_int16_t, void *) = (void *)(function);//->error
    callback_friendrequest(&(m->fr), handle_friendrequest, m, userdata);
}

In CI think your code would work, but C++ will not let you implicitly cast a void* into some other pointer type. I would do

typedef void (*FunFriend)(void *, u_int8_t *, u_int8_t *, u_int16_t, void *);

.
.
.
FunFriend handle_friendrequest = (FunFriend)function;

Pointer handle_friendrequest has type

void (*)(void *, u_int8_t *, u_int8_t *, u_int16_t, void *)

Pointer function has type

void (*)(Messenger *, u_int8_t *, u_int8_t *, u_int16_t, void *)

These are two different function pointer types, which are completely incompatible with each other. You cannot use function to initialize handle_friendrequest , period.

It looks like you tried to cast function to void * as a workaround, but this makes no sense whatsoever. It simply will not compile. It strange to see you ask this question (if I understood it correctly), since the compiler is complaining about a meaningless invalid cast you yourself inserted into the code.

You have to make sure both function pointers have identical types, including identical parameter lists. That will fix the problem and eliminate the need for any casts. As long as the parameter lists are different, there is no solution, aside from ugly hacks.

It is just as the error message says. In the expression in your code, you have (void *)(function) .

That is of type void * . However you then assign that to a variable with function-pointer type. In general, it is not possible to convert between function pointers and object pointers, although some implementations may allow it.

If Messenger is actually a typedef for void * then you can just remove the (void *) because function and handle_friendrequest would have the same type, so no cast is necessary.

If Messenger is not void * then your intended code will have undefined behaviour, because the function pointers have different types. Consider re-doing your design so that the function you are calling actually has the same prototype as the type of the function pointer.

If you really want to bull on with the undefined behaviour, the code would be:

{
    typedef void HANDLER(void *, uint8_t *, uint8_t *, u_int16_t, void *);
    HANDLER *handle_friendrequest = (HANDLER *)function;
}
void (*handle_friendrequest)(void *, u_int8_t *, u_int8_t *, u_int16_t, void *) =
        (void (*)(void*, u_int8_t*, u_int8_t*, u_int16_t, void*))function;

Of course function must be aware that it may take void* , not Messenger *

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM