使用类成员函数作为回调?

时间:2011-10-25 07:00:25

标签: c++

我需要将成员函数传递给第三方外部方法:

box_self_intersection_d(mycallback);

box_self_intersection_d是第三方外部静态方法,我无法修改它。 mycallback是我希望将其传递给box_self_intersection_d的方法,它是一个类函数,并且正在访问此类中的某些成员(对此类具有完全控制权并且mycallback)< / p>

无论如何我可以使用类成员函数作为回调而不将它们声明为静态函数吗?

修改:mycallback的签名为(const box &boxA, const box &boxB),其中box是来自第三方提供商的特殊类。

signature for box_self_intersection_d

void box_self_intersection_d(RandomAccessIterator begin,RandomAccessIterator end,Callback callback)

6 个答案:

答案 0 :(得分:1)

如果回调接受用户定义数据的void *,则可以使用静态包装函数将void *参数强制转换为类类型并调用成员函数。

示例:

static void Foo::callback_method(void* data) {
    static_cast<Foo*>(data)->mycallback();
}

void Foo::register_my_callback() {
    box_self_intersection_d(&Foo::callback_method, this);
}

大多数理智的回调库允许您将此void *参数传递给函数,作为在其中包含用户定义数据的方法。如果没有,你需要采用脏方法:

static Foo* Foo::callback_object;
static void Foo::callback_method() {
    callback_object->mycallback();
}

void Foo::register_my_callback() {
    callback_object = this;
    box_self_intersection_d(&Foo::callback_method);
}

一般来说,如果你需要传递一个函数,就没有别的方法:要么你有一个像void *这样的数据旁道,你的库提供者似乎已经省略了(这显然是一个错误)库),或者您需要通过全局变量传输this指针。

答案 1 :(得分:1)

如果函数box_self_intersection_d将函数作为参数,而mycallback是类MyClass的方法,则可以使用boost::bind

box_self_intersection_d( boost::bind( &MyClass::mycallback, myClassInstance ) );

其中myClassInstance是类MyClass的实例。

答案 2 :(得分:0)

有几种可能的解决方法。您可以在这里查看:http://www.newty.de/fpt/callback.html#member

简而言之,您可以:

  • 声明一个静态的“包装器方法”并将类的实例传递给它,
  • 或者将指向对象的指针存储为全局变量。

希望有所帮助,

答案 3 :(得分:0)

您尚未提供签名 box_self_intersection_d()

一般来说,如果签名是

void box_self_intersection_d( void *cb );

甚至

void box_self_intersection_d( void (*cb)(const box&, const box&) );

然后你不能传递给成员函数的指针。

原因是sizeof(a_member_function)不同于 sizeof(a_function_pointer)。如果是这种情况,我认为你被迫使用 thiton 的解决方案,并创建一个静态函数。

答案 4 :(得分:0)

由于它是CGAL,回调实际上是一个模板参数 它唯一的限制是“回调必须是BinaryFunction概念” 也就是说,它可以是具有适当参数的“可调用”的任何东西。

这包括具有void operator() (const box&, const box&)成员函数的任何对象 在类中实现该函数并将*this传递给回调可能是最简单的解决方案。

答案 5 :(得分:0)

有一个可怕的解决方案,我可以想到这意味着将'this'和功能代码复制/推送到调用堆栈(或其他一些可以写入和可执行的调用者分配的段),并传递地址对图书馆的功能。然后,回调函数可以找到自己的代码地址,使用偏移量/指针arith提取“this”。并调用成员函数。应该适用于多个线程。

我特此声称这一年的'Gruesome Hack'奖项是一个解决方案,让开发人员感到身体不适,但如果项目经理指着霰弹枪在你头上,它可能仍然有效。

RGDS, 马丁