2

私は、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文字の3つのパラメーターがあります。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回はメソッドに入ることができたのに、なぜ次のエラーが発生するのかということです。マウスが窓の中で動いた瞬間に変化があると思います。誰か助けてくれませんか?

これが私がしていることの画像です:

エラーと結果のある画像

4

1 に答える 1

1

そのサンクコードは、__stdcallではなく規則を使用し__cdeclます。この場合、cvSetMouseCallbacktakesvoid*はコールバックに渡されるため、静的コールバック関数を使用し、このデータポインターを使用してポインターを渡すことをお勧めします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 );  
于 2012-01-02T00:17:00.130 に答える