First of all I have to admit that my programming skills are pretty limited and I took over a (really small) existing C++ OOP project where I try to push my own stuff in. Unfortunately I'm experiencing a problem which goes beyond my knowledge and I hope to find some help here. I'm working with a third party library (which cannot be changed) for grabbing images from a camera and will use some placeholder names here.
The third party library has a function "ThirdPartyGrab" to start a continuous live grab and takes a pointer to a function which will be called every time a new frame arrives. So in a normal C application it goes like this:
ThirdPartyGrab (HookFunction);
"HookFunction" needs to be declared as:
long _stdcall HookFunction (long, long, void*);
or "BUF_HOOK_FUNCTION_PTR" which is declared as
typedef long (_stdcall *HOOK_FUNCTION_PTR) (long, long, void*);
Now I have a C++ application and a class "MyFrameGrabber" which should encapsulate everything I do. So I put in the hook function as a private member like this:
long _stdcall HookFunction (long, long, void*);
Also there is a public void function "StartGrab" in my class which should start the Grab. Inside I try to call:
ThirdPartyGrab (..., HookFunction, ...);
which (not surprisingly) fails. It says that the function call to MyFrameGrabber::HookFunction misses the argument list and I should try to use &MyFrameGrabber::HookFunction to create a pointer instead. However passing "&MyFrameGrabber::HookFunction" instead results in another error that this cannot be converted to BUF_HOOK_FUNCTION_PTR.
After reading through the C++ FAQ function pointers I think I understand the problem but can't make up a solution. I tried to make the hook function static but this also results in a conversion error. I also thought of putting the hook function outside of the class but I need to use class functions inside the hook function. Is there another way or do I need to change my whole concept?
EDIT 14.01.08: I tested the singleton workaround since I cannot change the third party library and the void pointer is only for data that is used inside the hook function. Unfortunately it didn't worked out of the box like I hoped.... I don't know if the static function needs to be in a separate class so I put it in my "MyFrameGrabber" class:
static MyFrameGrabber& instance()
{
static MyFrameGrabber _instance;
return _instance;
}
long Hook(long, long, void*); // Implementation is in a separate cpp file
In my cpp file I have the call_hook function:
long MFTYPE call_hook(long x, MIL_ID y, void MPTYPE *z)
{
return MyFrameGrabber::instance().Hook(x,y,z);
}
void
MyFrameGrabber::grab ()
{
ThirdPartyGrab(..., call_hook, ...);
}
But this gives me an error in static MatroxFrameGrabber _instance;
that no matching standard constructor is found. That's correct because my MyFrameGrabber constructor looks like this:
MyFrameGrabber (void* x,
const std::string &y, int z,
std::string &zz);
I tried to put in an empty constructor MyFrameGrabber();
but this results in a linker error. Should I pass empty parameters to the MyFrameGrabber constructor in the singleton? Or do I need to have a separate Hook Class and if yes how could I access MyFrameGrabber functions? Thanks in advance.
SECOND EDIT 15.01.08: I applied the changes and it compiles and links now. Unfortunately I cannot test this at runtime yet because it's a DLL and I have no Debug Caller Exe yet and there are other problems during initialization etc. I will mark the post as answer because I'm sure this is the right way to do this.
See Question&Answers more detail:os