2012-01-02 8 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"); 
} 

これを実行すると、マウスをウィンドウの内側に移動しないと、okです。コールバックがcvSetMouseCallback関数に正常に渡されました。 cvSetMouseCallback関数には、3つのパラメータがあります。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呼び出し規約に準拠していると仮定しています。

私の質問は、ウィンドウにマウスを置いたときに、少なくとも1回はメソッドに入ることができたら、どうして次のエラーが出るのですか?私はマウスがウインドー内で動く2番目の瞬間に変化があると思う。誰も私を助けることができますか?

は、ここで私がやっているものとイメージだ:コードをサンク

Image with error and results

答えて

1

__stdcall大会、ない__cdeclを使用しています。この場合、cvSetMouseCallbackvoid*をコールバックに渡すので、静的コールバック関数を使用してこのデータポインタを使用して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

これを行うにはどうすればよいですか? –

+0

おおよその例を参照してください –

+0

あなたが持っているstaticMouseHandler関数内のMouseHandlerは、それは何ですか?どういうわけか、それは動作していません。 –

関連する問題