2013-07-11 4 views
5

タイトルが示唆するように、OpenCVのmouseCallback関数をクラスベースのC++構造体で実装する際に問題があります。私に説明させてください。私はBriskMatchingというクラスを定義しました。このクラスでは、OpenCVが必要とする正しいパラメータでmouseCallbackという名前のメンバ関数を作成しました(下記のコードをご覧ください)。私はOpenCVののcv::setMouseCallback機能によって指定されたマウスのコールバック関数として、この機能を設定しようとするOpenCVのmouseCallback関数のクラスベースの実装を作成するのに問題がある

**Briskmatching.h** 

class BriskMatching 
{ 
public: 
    BriskMatching(); 
    ~BriskMatching(); 

public: 
    void mouseCallback(int event, int x, int y, int flags, void *param); 
}; 

これは、すべての罰金ですが、しかし、私の問題が発生します。私の主な機能には

、私はbriskMatcherと呼ばれるBriskMatchingクラスのインスタンスを作成し、それは私がそうのようにそれを行うにしようとするマウスのコールバックを設定するための時間が来るとき...

cv::setMouseCallback("Matches", BriskMatching::mouseCallback, &matchesImg); 

残念ながら、これはスローエラー。

Error 3 error C3867: 'BriskMatching::mouseCallback': function call missing argument list; use '&BriskMatching::mouseCallback' to create a pointer to member c:\users\mobilef\documents\visual studio 2010\projects\opencv_objtracking\opencv_briskmatching\main.cpp 54 1 OpenCV_BriskMatching 

私はBriskMatching.hstaticようmouseCallback関数を宣言することで、このエラーを取り除くことができますが、私はmouseCallback機能の多くの非静的メンバ変数を参照するので、私は他のエラーの全体の強打を取得します。

あなたに私の質問はこれです。 BriskMatchingクラス内で宣言されたmouseCallback関数をcv::setMouseCallback関数に正しく渡すために、コードをどのように変更する必要がありますか?

アドバイスをいただきありがとうございます。

答えて

12

メンバー関数にはthisポインターが必要なため、静的ラッパー関数が必要です。 mouseCallback内部

... 
static void mouseCallback(int event, int x, int y, int flags, void *param); 

void doMouseCallback(int event, int x, int y, int flags); 

そして:

void BriskMatching::mouseCallback(int event, int x, int y, int flags, void *param) 
{ 
    BriskMatching *self = static_cast<BriskMatching*>(param); 
    self->doMouseCallback(event, x, y, flags); 
} 
+0

完璧、ありがとう!それは素晴らしいですが、私はそれの背後にあるロジックやその仕組みを完全に理解していません。私は数年前からC++でコーディングしてきましたが、タイプキャストは避けていました。私は今それらを読んで行くつもりです、そして、これがどのように働くかを理解しようとします。 – szakeri

0

あなたはこのようなものになってしまうので、一般的に、あなたは、メンバ関数が属するオブジェクトのアドレスであることをparamパラメータを使用します私はこのメソッドも使用していましたが、静的ヘルパークラスは非常に厳格で、型とメソッドの束縛であることに気付きました。

ただ、さらに参考のために私がどのように見えるテンプレートフリー機能定義しました:

template<typename TClass, void (TClass::*MouseClickType)(int, int, int, int)> 
void FreeOnMouseCallback(int event, int x, int y, int flags, void* ptr) 
{ 
    auto* mcPtr = static_cast<TClass*>(ptr); 
    if(mcPtr != NULL) 
    { 
     (mcPtr->*MouseClickType)(event, x, y, flags); 
    } 
} 

を私は今、

でクラス内の(名前の署名を照合ではなく)任意の関数を呼び出すことができます
cv::setMouseCallback(WindowName, FreeOnMouseCallback<Calibrator, &Calibrator::OnMouseCallback>, this); 

void * ptrも必要な場合は、拡張される可能性がありますが、ここでは省略しています。

関連する問題