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