我正在使用 OpenCV 库、Boost 库和我从这个 LINK 下载的一段代码编写应用程序.我在与 Thunk32 相同的解决方案下创建了一个项目,我有以下文件:
MainProject.cpp
#include "stdafx.h"
int main( int argc, char** argv )
{
IplImage *img = cvLoadImage( "C:/Users/Nicolas/Documents/Visual Studio 2010/Projects/OpenCV_HelloWorld/Debug/gorilla.jpg" );
Window::WindowType1 *win = new Window::WindowType1("Something");
cvNamedWindow( "window", CV_WINDOW_AUTOSIZE );
cvShowImage( "window", img );
cvSetMouseCallback( "oonga", (CvMouseCallback)win->simpleCallbackThunk.getCallback(), NULL );
while( true )
{
int c = waitKey( 10 );
if( ( char )c == 27 )
{ break; }
}
return 0;
}
Window.h
class Window {
public:
Window();
virtual ~Window();
//virtual void mouseHandler( int event, int x, int y, int flags, void *param );
private:
void assignMouseHandler( CvMouseCallback mouseHandler );
class WindowWithCropMaxSquare;
class WindowWithCropSelection;
class WindowWithoutCrop;
public:
typedef WindowWithCropMaxSquare WindowType1;
typedef WindowWithCropSelection WindowType2;
typedef WindowWithoutCrop WindowType3;
protected:
};
class Window::WindowWithCropMaxSquare : public Window {
public:
indev::Thunk32<WindowType1, void _cdecl ( int, int, int, int, void* )> simpleCallbackThunk;
WindowWithCropMaxSquare( char* name );
~WindowWithCropMaxSquare();
void _cdecl mouseHandler( int event, int x, int y, int flags, void *param );
private:
protected:
};
和Window.cpp
#include "stdafx.h"
Window::Window()
{
}
Window::~Window()
{
}
void Window::assignMouseHandler( CvMouseCallback mouseHandler )
{
}
Window::WindowWithCropMaxSquare::WindowWithCropMaxSquare( char* name )
{
simpleCallbackThunk.initializeThunk(this, &Window::WindowWithCropMaxSquare::mouseHandler); // May throw std::exception
}
Window::WindowWithCropMaxSquare::~WindowWithCropMaxSquare()
{
}
void _cdecl Window::WindowWithCropMaxSquare::mouseHandler( int event, int x, int y, int flags, void *param )
{
printf("entered mousehandler");
}
现在,当我运行它时,如果我没有在窗口内移动鼠标,就可以了,并且回调已成功传递给 cvSetMouseCallback 函数。 cvSetMouseCallback 函数具有三个参数 1. 窗口名称, 2. CvMouseCallback 和 NULL 字符。 CvMouseCallback 定义为
typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param);
而 CV_CDECL 只是对 _cdecl 调用约定的重新定义。
#define CV_CDECL __cdecl
现在,我的 mouseHandler 函数是一个类成员函数,我假设它符合 _thiscall 调用约定。
我的问题是,为什么我将鼠标放在窗口上时会出现以下错误,如果它至少成功进入了该方法一次?我想当我的鼠标在窗口内移动的那一刻发生了变化。谁能帮帮我?
这是我正在做的事情的图片:
最佳答案
thunk 代码使用 __stdcall
约定,而不是 __cdecl
。在这种情况下,由于 cvSetMouseCallback
接受一个 void*
并将其传递给回调,我建议您使用静态回调函数并使用此数据指针传递this
指针。然后,您可以将您的逻辑放在这个静态函数中,或者使用传入的指针调用回调的实例版本。
class Window {
public:
void _cdecl staticMouseHandler( int event, int x, int y, int flags, void *param ) {
((MouseHandler*)param)->mouseHandler(event, x, y, flags, NULL);
}
// ...
}
// ...
cvSetMouseCallback( "oonga", &Window::staticMouseHandler, win );
关于windows - ESP 的值未正确保存....和 C/C++ 调用约定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8696436/