【问题标题】:member function pointer and callbacks成员函数指针和回调
【发布时间】:2011-06-03 09:59:14
【问题描述】:

嗨 我正在尝试传递一个作为成员函数的回调。我知道函数指针和成员函数指针是不同的,并尝试创建一个包装器并使用静态强制转换和 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); 

如果有人能澄清我做错了什么以及为什么会非常感激。

弗雷德

【问题讨论】:

  • dSpaceCollide的签名是什么?
  • “我知道函数指针和成员函数指针是不同的,并且已经尝试过 [...] 静态转换”。不知怎的,我想你不明白。演员表不是让你的问题消失的魔杖。
  • 是的,没有 dSpaceCollide 的签名我只能猜测。在 dSpaceCollide 的调用中接受的函数指针中可能没有 userPtr 参数?还是没有数据参数?
  • 为什么在你定义static int StaticNearCallback的类中,后来又被用作void ODEPhysics::StaticNearCallback?...
  • dSpaceCollide 的签名是

标签: c++ function pointers callback member


【解决方案1】:

根据您的显示,问题很可能是dSpaceCollide 只是想要一个

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

回调,即一个函数,一个void*用户数据指针和两个dGeomIDs作为参数。 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

【讨论】:

  • 感谢 Xeo,很好的解释
【解决方案2】:

我会在这里猜测,并假设typedef void dNearCallback(void *data, dGeomID o1, dGeomID o2)。也就是说,没有void* userPtr 传递给您的回调。当您尝试使用 StaticNearCallback 时,类型系统会捕捉到这一点,确实需要 void* userPtr

这个问题的根本原因可能是一个更根本的误解。为什么您的StaticNearCallback两个 未类型化的void* 指针?你在用NearCallback 中的void* data 做什么?记住,C++ 方法有一个(类型化的)this 指针,所以你很少需要一个非类型化的void* data

【讨论】:

    【解决方案3】:

    看看boost::function(也许还有boost::bind)。它们通常可以让您的生活更轻松。

    【讨论】:

    • 如果你的回调需要一个简单的函数指针,它们不会。
    • @Xeo。嗯,是。我假设他也负责调用类。
    猜你喜欢
    • 2018-09-12
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-16
    • 2016-08-17
    • 2018-05-22
    相关资源
    最近更新 更多