Fred
Fred

Reputation: 35

member function pointer and callbacks

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

Answers (3)

Roddy
Roddy

Reputation: 68023

Have a look at boost::function (and maybe boost::bind). They can often make your life a lot easier.

Upvotes: 0

Xeo
Xeo

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 dGeomIDs 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

MSalters
MSalters

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

Related Questions