首先,一些背景:
(注意:虽然我在非.NET Win32领域,但这确实是一个C ++问题)
我正在使用第三方API,要求您注册回调函数以了解异步操作何时完成。必须使用回调,不能绕过它。
非OOP实现将是这样的:
void __stdcall MyCbFcn(int value)
{
do something with 'value'...
}
API_RegisterCallback(MyCbFcn);
非常标准的东西。
但是...
我的代码是OOP,有多个实例rx'回调,因此回调需要路由到注册它的对象。
知道人们这样做,回调通常包括用户var,如:
void __stdcall MyCbFcn(int value, U32 user)
{
do something with 'value'...
}
API_RegisterCallback(MyCbFcn, someUserValue);
更具体地说,当与OOP结合使用时,此用户arg允许您返回上下文:
(为简洁而内省编写):
class MyClass
{
public:
MyClass()
{
API_RegisterCallback(MyClass::StaticCbFcn, (U32)this);
}
private:
static void __stdcall StaticCbFcn(int value, U32 user)
{
MyClass* pThis = (MyClass*)user;
pThis->InstanceCbFcn(value);
}
void InstanceCbFcn(int value)
{
... do some work in context ...
}
}
但是,我的API没有用户arg :(
所以现在我的问题:
我怎样才能回到上下文中?
我认为有点粗略的事情,比如定义一个包含100个不同回调的“池”,并将它们分配为对象,但这似乎是一个真正的黑客。
一个明显的解决方案......如果我在JavaScript :) ...将使用匿名函数,但AFAIK C ++没有这样的东西。
任何想法都会受到赞赏。
答案 0 :(得分:2)
“100个不同的回调”是你唯一可以做的事情,因此你使用函数地址作为识别参数。使用常量参数将不同的函数实现为模板可能会有所帮助:
template < unsinged N >
void StaticCbFcn( int value )
{
map[ N ].InstanceCbFcn( value );
}