C++ 如果回调函数没有';你没有这样的参数吗?

C++ 如果回调函数没有';你没有这样的参数吗?,c++,callback,C++,Callback,通常回调函数应该有一个可用于对象指针的“上下文”参数,但是对于没有此类参数的遗留代码,有什么好的方法来伪造它呢 我经常需要编写代码来调用库并从库中接收回调调用,但是回调必须在对象的上下文中实际运行 我通常通过使用一个静态函数作为回调来假装这一点,而回调又包含一个静态变量,我将该变量设置为对象指针,然后在该指针上调用一个成员函数。这是我对Microsoft的FMIFS库的回调: // Return TRUE for Continue, FALSE for Cancel /* static */ B

通常回调函数应该有一个可用于对象指针的“上下文”参数,但是对于没有此类参数的遗留代码,有什么好的方法来伪造它呢

我经常需要编写代码来调用库并从库中接收回调调用,但是回调必须在对象的上下文中实际运行

我通常通过使用一个静态函数作为回调来假装这一点,而回调又包含一个静态变量,我将该变量设置为对象指针,然后在该指针上调用一个成员函数。这是我对Microsoft的FMIFS库的回调:

// Return TRUE for Continue, FALSE for Cancel
/* static */ BOOLEAN CALLBACK CFmifsCallbackHelper::FmifsCallback
(
    zFmifsCallbackCommand Command, 
    DWORD                 Modifier, 
    PVOID                 Argument
)
{
    static CFmifsCallbackHelper* helper = NULL;

    if (Command == zFmifsCallbackCommandInvalid)
    {
        helper = reinterpret_cast<CFmifsCallbackHelper*>(Argument);
        return TRUE;
    }
    else if (helper)
    {
        BOOLEAN retValue = helper->Callback(Command, Modifier, Argument);
        return retValue;
    }
    return TRUE;
}
//返回TRUE表示继续,返回FALSE表示取消
/*静态*/BOOLEAN回调CFmifsCallbackHelper::fmifscalback
(
zFmifsCallbackCommand命令,
德沃德修饰符,
PVOID参数
)
{
静态cfmifscalbackhelper*helper=NULL;
如果(命令==ZFMIFiscalBackCommandInvalid)
{
helper=reinterpret_cast(参数);
返回TRUE;
}
else if(助手)
{
布尔retValue=helper->Callback(命令、修饰符、参数);
返回值;
}
返回TRUE;
}

因此,在将静态回调函数实际用作回调函数之前,需要使用一个“误用”参数调用它一次。只有当参数至少为指针大小时,静态回调函数才有效,并且不能同时调用不同的上下文。此外,我需要绝对确保库永远不会使用用于设置上下文(
helper
)的
命令值(
zfmiffscalbackcommandinvalid
)。总的来说很糟糕。有没有更干净的方法来实现这一点?

我不确定我是否理解这个问题。为什么不直接将上下文传递到回调函数中呢?上下文需要由库传递,但不是。参数
参数
不适用于该用途,而是由库用于其他数据。(并且库函数,例如
格式
Chkdsk
也不接受上下文参数)。是否可以使用线程本地存储?i、 e.使用当前线程作为索引(散列键)创建一个上下文数组,然后回调可以使用当前线程查找上下文。当回调工作完成时,请确保清除线程/上下文。如果我正确理解了您的代码,请使用
参数
计算
帮助程序
。如果参数“大小不够”,则可以使用静态映射
参数
=>
cfmifscalbackhelper*
。另外,我不明白为什么“函数需要用一个“误用”参数调用一次”在实际调用过程中不可能“懒惰”初始化指向对象的指针吗?您可能需要花一些时间查看库的文档/教程。他们会显式地提供一个
PVOID
参数(我假设它是
void*
的别名),然后让您无法访问/不方便,这似乎很奇怪。我不确定我是否理解这个问题。为什么不直接将上下文传递到回调函数中呢?上下文需要由库传递,但不是。参数
参数
不适用于该用途,而是由库用于其他数据。(并且库函数,例如
格式
Chkdsk
也不接受上下文参数)。是否可以使用线程本地存储?i、 e.使用当前线程作为索引(散列键)创建一个上下文数组,然后回调可以使用当前线程查找上下文。当回调工作完成时,请确保清除线程/上下文。如果我正确理解了您的代码,请使用
参数
计算
帮助程序
。如果参数“大小不够”,则可以使用静态映射
参数
=>
cfmifscalbackhelper*
。另外,我不明白为什么“函数需要用一个“误用”参数调用一次”在实际调用过程中不可能“懒惰”初始化指向对象的指针吗?您可能需要花一些时间查看库的文档/教程。他们会显式地提供一个
PVOID
参数(我假设它是
void*
的别名),然后让您无法访问/不方便,这似乎很奇怪。