Reputation: 35
Hi I am trying to pass a callback which is a member function. I understand that a function pointer and a member function pointer are different and have tried to create a wrapper and use a static cast and the void pointer. Unfortunately I am missing something as my code produces an error at compile
Error 16 error C2664: 'dSpaceCollide' : cannot convert parameter 3 from 'int (__cdecl *)(void *,void *,dGeomID,dGeomID)' to 'dNearCallback (__cdecl *)'
My code.....
class ODEPhysics
header file
void NearCallback (void* data, dGeomID o1, dGeomID o2);
static int StaticNearCallback(void* data, void* userPtr, dGeomID o1, dGeomID o2);
.cpp file
void ODEPhysics::NearCallback (void* data, dGeomID o1, dGeomID o2){.........}
void ODEPhysics::StaticNearCallback(void* data , void* userPtr, dGeomID o1, dGeomID o2)
{
static_cast<ODEPhysics*>(userPtr)->NearCallback( data, o1, o2);
}
dSpaceCollide (Space, 0, &ODEPhysics::StaticNearCallback);
If anyone could clarify what I am doing wrong and why it would be greatly appreciated.
Fred
Upvotes: 1
Views: 1198
Reputation: 68023
Have a look at boost::function (and maybe boost::bind). They can often make your life a lot easier.
Upvotes: 0
Reputation: 131789
The problem is most likely, from what you show, that dSpaceCollide
just wants a
typedef void (*dNearCallback)(void*,dGeomID,dGeomID)
callback, that is, a function with a single void*
user-data pointer and the two dGeomID
s as parameters. The void*
is whatever data you passed to the dSpaceCollide
then.
Assuming dSpaceCollide
is defined something like this:
void dSpaceCollide(CSpace s, void* user_data, dNearCallback cb){
// somewhere inside the code it will call your callback:
cb(user_data, some_other, params);
// ...
}
You can then change the callbacks to this:
void NearCallback(dGeomID o1, dGeomID o2);
static void StaticNearCallback(void* data, dGeomID o1, dGeomID o2){
ODEPhysics* self = static_cast<ODEPhysics*>(data);
self->NearCallback(o1, o2);
}
No more need for the void* data
pointer in the member function, as that data
is only relevant for the static callback:
// assuming you call this inside of your ODEPhysics class
dSpaceCollide(Space, this, &ODEPhysics::StaticNearCallback);
// pass this as user_data
Upvotes: 1
Reputation: 179779
I'm going to guess here, and assume typedef void dNearCallback(void *data, dGeomID o1, dGeomID o2)
. That is to say, there's no void* userPtr
passed to your callback. The type system catches this when you try to use StaticNearCallback
, which does expect a void* userPtr
.
Underlying this problem might be a more fundamental misunderstanding. Why does your StaticNearCallback
have two untyped void*
pointers? What are you doing with void* data
in NearCallback
? Remember, C++ methods have a (typed) this
pointer, so you rarely need an untyped void* data
.
Upvotes: 0