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

Use class member functions as callbacks?

本文关键字:函数 回调 成员      更新时间:2023-10-16

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

box_self_intersection_d(mycallback);

box_self_intersection_d是第三方外部静态方法,我无法修改。mycallback是一个方法,我想把它传递给box_self_intersection_d,它是一个类函数,正在访问这个类中的一些成员(完全控制这个类和mycallback)

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

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

box_self_intersection_d的签名是
void box_self_intersection_d(RandomAccessIterator begin,RandomAccessIterator end,Callback callback)

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

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

其中myClassInstance是类MyClass的实例

如果回调接受用户定义数据的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*参数传递给函数,作为一种包含用户定义数据的方式。如果没有,则需要使用dirty方法:

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*这样的数据侧通道,你的库提供程序似乎省略了(这显然是库中的一个bug),要么你需要通过一个全局变量来传输this指针。

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

简而言之,您可以:

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

希望有帮助,

您没有提供签名 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)。如果是这种情况,我认为您必须使用的解决方案,并创建一个静态函数

因为它是CGAL,所以回调实际上是一个模板参数。
它唯一的约束是"Callback必须是BinaryFunction的概念"。
也就是说,它可以是任何带有适当参数的"可调用"的对象。

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

有一个可怕的解决方案,我可以想象,这意味着复制/推'this'和函数代码到调用堆栈,(或其他一些调用者分配的段,可以写和可执行),并传递函数的地址到库。然后回调函数可以找到自己的代码地址,使用偏移量/指针算术提取'this'。调用一个成员函数。

我在此宣布今年的"可怕的黑客"奖,因为这个解决方案让开发人员感到身体不适,但如果项目经理用猎枪指着你的头,它可能仍然有效。

祝好,马丁