указатель на функцию-член и обратные вызовы - PullRequest
1 голос
/ 03 июня 2011

Привет Я пытаюсь передать обратный вызов, который является функцией-членом. Я понимаю, что указатель на функцию и указатель на функцию-член различаются и пытались создать оболочку и использовать статическое приведение и указатель void. К сожалению, я что-то упустил, так как мой код выдает ошибку при компиляции

Error   16  error C2664: 'dSpaceCollide' : cannot convert parameter 3 from 'int (__cdecl *)(void *,void *,dGeomID,dGeomID)' to 'dNearCallback (__cdecl *)'  

Мой код .....

class ODEPhysics

заголовочный файл

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); 

Если бы кто-нибудь мог уточнить, что я делаю неправильно и почему это было бы очень признательно.

Fred

Ответы [ 3 ]

1 голос
/ 03 июня 2011

Скорее всего, из того, что вы показываете, проблема в том, что dSpaceCollide просто хочет

typedef void (*dNearCallback)(void*,dGeomID,dGeomID)

обратный вызов, то есть функция с одним void* указателем пользовательских данных и двумя dGeomID s в качестве параметров. void* - это любые данные, которые вы передали dSpaceCollide тогда.

Предполагается, что dSpaceCollide определено примерно так:

void dSpaceCollide(CSpace s, void* user_data, dNearCallback cb){
  // somewhere inside the code it will call your callback:
  cb(user_data, some_other, params);
  // ...
}

Затем вы можете изменить обратные вызовы на это:

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);
}

Больше не требуется указатель void* data в функции-члене, поскольку data относится только к статическому обратному вызову:

// assuming you call this inside of your ODEPhysics class
dSpaceCollide(Space, this, &ODEPhysics::StaticNearCallback);
// pass this as user_data
0 голосов
/ 03 июня 2011

Посмотрите на boost :: function (и, возможно, boost :: bind ).Они часто могут сделать вашу жизнь намного проще.

0 голосов
/ 03 июня 2011

Я собираюсь угадать здесь и предположить typedef void dNearCallback(void *data, dGeomID o1, dGeomID o2).То есть void* userPtr не передано вашему обратному вызову.Система типов ловит это, когда вы пытаетесь использовать StaticNearCallback, что действительно ожидает void* userPtr.

В основе этой проблемы может быть более фундаментальное недоразумение.Почему ваши StaticNearCallback имеют два нетипизированных void* указателя?Что вы делаете с void* data в NearCallback?Помните, что методы C ++ имеют (типизированный) указатель this, поэтому вам редко требуется нетипизированный void* data.

...