Nicolas Epaminonda
Nicolas Epaminonda

Reputation: 191

Function pointers and callbacks

I am using Microsoft Visual Studio 2010 and the OpenCV 2.3.0 libraries to write up an application for image processing.

I have a piece of code that is erroneous for me and I am not sure how to fix it. I am implementing an application where there will be 2 or 3 windows open at the same time and I want each one of them to be assigned with a different CvMouseCallback function. I want all these CvMouseCallback functions to be in a different class together with another function that returns a pointer to one of these functions according to what the user selects.

My Window.h contains this piece of code.

class Window
{
public:
   ... // constructors and destructors
   void setMouseHandler( CvMouseCallback mouseHandler );
private:
   ... // other stuff
};

and Window.cpp

#include "stdafx.h"

void Window::setMouseHandler( CvMouseCallback mouseHandler )
{
    cvSetMouseCallback( win, mouseHandler, NULL );
}

Now, the MouseHandler.h file

class MouseHandler
{
public:
   ...
   CvMouseCallback selectHandler( int option );
   void __cdecl selectROI( int event, int x, int y, int flags, void *param );

private:
   Image *in;
   Window *win;
   void ( CV_CDECL MouseHandler::*callback )( int event, int x, int y, int flags, void *param );
};

and lastly, in MouseHandler.cpp I contain

void __cdecl MouseHandler::selectROI( int event, int x, int y, int flags, void *param )
{
   //do something
}

CvMouseCallback MouseHandler::selectHandler( int option )
{
   callback = (MouseHandler::selectROI);
   return callback;
}

The last bit of information you might need is the definition of CvMouseCallback from the OpenCV library which is

typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param);

Now, the question is: When I return the callback from the last function in MouseHandler.cpp it is underlined with an error saying:

Error: return value type does not match the function type.

I know what it says is that I am trying to impose to that function to return something that does not look like the object it is being asking for. However, it's just a function and if I could do that in the main class it would be ok. My problem is how can selectHandler return a pointer to the selectROI function so that it can be used by another class?

Upvotes: 0

Views: 1255

Answers (2)

John Zwinck
John Zwinck

Reputation: 249103

Your selectROI() method, since it is not static, requires an implicit this parameter as its first argument. If you try making it static, you will have a better chance at getting it working, though really if you are passing it to a C API as you are, you technically need to pass an extern "C" function pointer for everything to be fully proper and portable. That might be a trivial forwarding function like this:

extern "C" void selectROI( int event, int x, int y, int flags, void *param );

Then, if you want your C++ class method to not be static (so it can access class member variables), you just need to pass a pointer to a MouseHandler object as the third argument to cvSetMouseCallback() and you will then receive the same in your callback, which can then look like this:

extern "C" void selectROI( int event, int x, int y, int flags, void *param )
{
    static_cast<MouseHandler*>(param)->selectROI( event, x, y, flags);
}

Upvotes: 1

littleadv
littleadv

Reputation: 20262

I think that you need to use a static function here:

static void __cdecl selectROI( int event, int x, int y, int flags, void *param );

and

void ( CV_CDECL *callback )( int event, int x, int y, int flags, void *param );

accordingly.

The thing is that this definition:

typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param);

Is not a class member function, while yours is a member of class MouseHandler, which means its a different signature and different parameter list (to accommodate for this). Using static class member function solves it for you.

You'll have to figure out how to pass the object context data to the static function of course.

Upvotes: 1

Related Questions