函数指针和回调函数
Function pointers and callbacks
我使用Microsoft Visual Studio 2010和OpenCV 2.3.0库编写了一个图像处理应用程序。
我有一段对我来说是错误的代码,我不知道如何修复它。我正在实现一个应用程序,其中将有2或3个窗口同时打开,我希望它们中的每一个都被分配一个不同的CvMouseCallback函数。我希望所有这些CvMouseCallback函数与另一个函数一起在不同的类中,该函数根据用户选择的内容返回指向其中一个函数的指针。
My windows .h包含这段代码。
class Window
{
public:
... // constructors and destructors
void setMouseHandler( CvMouseCallback mouseHandler );
private:
... // other stuff
};
和 Window.cpp
#include "stdafx.h"
void Window::setMouseHandler( CvMouseCallback mouseHandler )
{
cvSetMouseCallback( win, mouseHandler, NULL );
}
现在,MouseHandler.h文件
class MouseHandler
{
public:
...
CvMouseCallback selectHandler( int option );
void __cdecl selectROI( int event, int x, int y, int flags, void *param );
private:
Image *in;
Window *win;
void ( CV_CDECL MouseHandler::*callback )( int event, int x, int y, int flags, void *param );
};
最后,在MouseHandler.cpp中包含
void __cdecl MouseHandler::selectROI( int event, int x, int y, int flags, void *param )
{
//do something
}
CvMouseCallback MouseHandler::selectHandler( int option )
{
callback = (MouseHandler::selectROI);
return callback;
}
您可能需要的最后一点信息是来自OpenCV库的CvMouseCallback的定义
typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param);
现在,问题是:当我从MouseHandler.cpp中的最后一个函数返回回调时,它下划线显示错误:
错误:返回值类型与函数类型不匹配
我知道它说的是我试图强加给那个函数返回的东西看起来不像它正在请求的对象。然而,它只是一个函数,如果我能在主类中做到这一点,那就没问题了。我的问题是如何selectHandler返回一个指向selectROI函数的指针,以便它可以被另一个类使用?
我认为您需要在这里使用static
函数:
static void __cdecl selectROI( int event, int x, int y, int flags, void *param );
和
void ( CV_CDECL *callback )( int event, int x, int y, int flags, void *param );
相应的。
问题是这个定义:
typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param);
不是类成员函数,而您的函数是类MouseHandler
的成员,这意味着它有不同的签名和不同的参数列表(以适应this
)。使用static
类成员函数为您解决了这个问题。
您必须弄清楚如何将对象上下文数据传递给static
函数。
您的selectROI()
方法,因为它不是静态的,需要一个隐式的this
参数作为它的第一个参数。如果你尝试使它静态,你将有一个更好的机会让它工作,虽然实际上,如果你是传递给一个C API,你技术上需要传递一个extern "C"
函数指针,一切都是完全正确和可移植的。这可能是一个简单的转发函数,像这样:
extern "C" void selectROI( int event, int x, int y, int flags, void *param );
然后,如果你想让你的c++类方法不是静态的(所以它可以访问类成员变量),你只需要传递一个指向MouseHandler对象的指针作为cvSetMouseCallback()
的第三个参数,然后你将在你的回调中接收到相同的参数,然后看起来像这样:
extern "C" void selectROI( int event, int x, int y, int flags, void *param )
{
static_cast<MouseHandler*>(param)->selectROI( event, x, y, flags);
}
- 以特征类型作为参数的泛型函数回调
- 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++函数回调:无法从成员函数转换为函数签名
- 如何编写一个通用函数回调测试类