使用类成员函数作为回调函数
Use class member functions as callbacks?
我需要一个成员函数传递给第三方外部方法:
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'。调用一个成员函数。
我在此宣布今年的"可怕的黑客"奖,因为这个解决方案让开发人员感到身体不适,但如果项目经理用猎枪指着你的头,它可能仍然有效。
祝好,马丁
- 以特征类型作为参数的泛型函数回调
- C# DllImport 调用非托管C++函数回调
- 为什么模板参数推导失败,std::函数回调的可变参数模板参数?
- std::包含 std::函数回调的多个包装器的向量不起作用
- 如何设置对类的私有函数的函数回调?
- 如何使用 c++11 函数回调声明多个模板参数
- sqlite3 更改函数回调参数 void* not用于 int* C++
- 如何知道 sqlite 中的函数"回调"是否返回了一些东西?
- Windows表单如何使用其他函数回调图表信息
- 如何在 c++ 结构中的 void* 变量中调用存储函数(回调)
- 将成员函数作为标准函数回调
- C++ 使用成员函数回调实现按钮
- std::函数回调,参数采用观察者模式(寄存器主题上的占位符)
- 使用可变参数模板从 Lua 函数回调 (C api) 中提取参数
- 在C++中使用派生类的静态方法作为函数回调
- 将libuv与函数结构一起使用,而不是函数回调
- 如何将函数回调传递给类成员
- c++类成员函数回调
- C++函数回调:无法从成员函数转换为函数签名
- 如何编写一个通用函数回调测试类