2012-01-02 82 views
2

我正在使用OpenCV庫,Boost庫和我從這個LINK下載的一段代碼編寫應用程序。我已創建了Thunk32相同的解決方案下的一個項目,我有以下文件:ESP的值沒有正確保存....和C/C++調用約定

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: 

}; 

窗口。 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調用約定。

我的問題是,當我將鼠標放在窗口上時,爲什麼會出現以下錯誤,如果它已設法至少進入一次該方法?我想在我的鼠標在風中移動的第二個時刻會發生變化。任何人都可以幫助我嗎?

這裏是一個圖像與我在做什麼:

Image with error and results

回答

1

這咚代碼使用__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); 
+0

你知道我該怎麼做? – 2012-01-02 01:20:38

+0

請參閱粗略示例 – 2012-01-02 01:32:16

+0

您擁有staticMouseHandler函數的MouseHandler,究竟是什麼?不知何故,它不工作。 – 2012-01-02 01:55:03