How to bind a memberfunction to a library callback? - c++

I am searching for a solutiuon to assign a memberfuction Callback to the extLibrary->OnNewFrame where OnNewFrame is a pointer-to-function type.
class Test
{
public:
void init();
void Callback(ImageDataType, int);
private:
};
void Test::init(){
extLibrary=new CameraLib;
extLibrary->OnNewFrame = Test::Callback;
//OnNewFrame is a pointer-to-function type
}
void Test::Callback(ImageDataType data, int n){
doImageProc();
}
If I change the Code above to static void Callback(ImageDataType, int), the code runs fine, but of course I can not access the variables of the Test Class in Callback .
I think I have to init the Class and pass the memberfunction to the lib's pointer-to-function type after, but I don't know how to do that properly.
EDIT
Sorry, this is my first post and I provided wrong and incomplete information. I will try to improve this post as far as I am able to.
To clarify what the library actually needs:
typedef void (__stdcall *GrabNewFrame) (HANDLE h, int i);
//this is the pointer to function definition
...
//after that in the lib-class:
class CameraLib
{
...
public:
GrabNewFrame OnNewFrame;
...
}
OnNewFrame gets called by the lib every time a frame arrives from the camera.
So as far as I know, I have to assign my own void function to OnNewFrame . Without OOP this works like a charm. But with classes I do not get a memberfunction assigned to OnNewFrame ...

Related

non-member function pointer as a callback in API to member function

I'm using an API that requires me to pass a function pointer as a callback. I'm trying to use this API from my class in C++ but I'm getting compilation errors.
The API definition is:
typedef void (__stdcall *STREAM_CALLBACK)(void *userdata);
__declspec(dllimport) int __stdcall set_stream_callback(
STREAM_CALLBACK streamCB, void *userdata);
One example file, provided by the third party, is:
void __stdcall streamCB(void *userdata)
{
// callback implementation
}
int main(int argc, const char argv[])
{
int mid = 0;
set_stream_callback(streamCB, &mid);
}
And that works fine.
However when I try to use that in a class, I have an error:
error C3867: 'MyClass::streamCB': function call missing argument list;
use '&MyClass::streamCB' to create a pointer to member
The suggestion to use
&MyClass::streamCB
doesn't work.
I understood that the set_stream_callback only accepts a non-member function.
The problem is very similar to
How can I pass a class member function as a callback?
in which Johannes makes a concise suggestion, however I do not understand it very well. Could anyone expand a bit, if I am correct that it is relevant to this question?
I have tried:
void __stdcall MyClass::streamCB(void *userdata)
{
// callback implementation
}
static void MyClass::Callback( void * other_arg, void * this_pointer ) {
MyClass * self = static_cast<ri::IsiDevice*>(this_pointer);
self->streamCB( other_arg );
}
//and in the constructor
int mid = 0;
set_stream_callback(&MyClass::Callback, &mid);
But
error C2664: 'set_stream_callback' : cannot convert parameter 1 from
'void (__cdecl *)(void *,void *)' to 'STREAM_CALLBACK'
How do I get around this?
Edit1: Also, I want to use userdata inside the streamCB callback.
The idea of calling a member function from a callback taking only non-member functions is to create a wrapper for you member function. The wrapper obtains an object from somewhere and then calls the member function. If the callback is reasonably well designed it will allow you to pass in some "user data" which you'd use to identify your object. You, unfortunately, left out any details about your class so I'm assuming it looks something like this:
class MyClass {
public:
void streamCB() {
// whatever
}
// other members, constructors, private data, etc.
};
With this, you can set up your callback like so:
void streamCBWrapper(void* userData) {
static_cast<MyClass*>(userData)->streamCB()
}
int main() {
MyClass object;
set_stream_callback(&streamCBWrapper, &object);
// ...
}
There are various games you can play with how to create the streamCBWrapper function (e.g., you can make it a static member of your class) but all come down to the same: you need to restore your object from the user data and call the member function on this object.
You can achieve what you want to do by turning the userdata into a property of MyClass. Then you don't have to pass it to MyClass::Callback, which would be impossible, since you can only pass one parameter, and it would be the object instance.
Here's an example.
void __stdcall MyClass::streamCB()
{
// callback implementation
}
static void MyClass::Callback(void * this_pointer ) {
MyClass * self = static_cast<MyClass>(this_pointer);
self->streamCB();
}
MyClass::MyClass(void *userdata) {
// do whatever you need to do with userdata
// (...)
// and setup the callback at C level
set_stream_callback(&MyClass::Callback, (void *)this);
}
In your example, the int mid variable would become a property of that class, and thus be accessible from the callback implementation streamCB.

Using libuv inside classes

I am trying to write a nodejs bindings for a C++ library and I seem to have hit a roadblock.
I am working on trying to make all the calls to the C++ library asynchronous and thats why I am using libuv. I am basically following this tutorial.
I want to be able to call class member functions from libuv's uv_queue_work. Have a look at this code --
class test {
private:
int data;
void Work(uv_work_t *req);
void After(uv_work_t *req);
public:
Handle<Value> Async(const Arguments& args) {
HandleScope scope;
Local<Function> callback = Local<Function>::Cast(args[0]);
int status = uv_queue_work(uv_default_loop(), **something**, Work, After);
assert(status == 0);
return Undefined();
}
};
Basically I expect the Work and After functions to work on the data element of the class. However this doesnt seem to work. I have tried typecasting the pointers to Work and After after from type void test::(*)(uv_work_t*) to void (*)(uv_work_t*). But that also doesnt seem to work.
Could you guys give me some tips on how to work around this??
So as you've realized, you cannot call the member functions directly.
The second argument "something" is of type uv_work_t, which has a member "void* data".
What you will need to do is create static methods inside your class for "Work" and "After", create a uv_work_t structure, and assign data to "this".
Once that is done inside your static "Work" and "After" methods you do a static cast on "req->data" (To your class type) and then call your member functions.
For example:
uv_work_t* baton = new uv_work_t();
baton->data = this;
int status = uv_queue_work(uv_default_loop(), baton, StaticWork, StaticAfter);
And then in the static methods
test* myobj = static_cast<test>(req->data);
myobj->Work();
And similar code for the StaticAfter function

Pass any member function of any class as a Callback function

I'm working on a OpenGL menu which contains some buttons. I want to be able to associate an action (member function (with a fixed signature) of any class!) to a button which gets executed when the button is pressed. I can do it right now but only for one type. I want to be able to use any member function of any class for my callback.
Right now I'm doing it like this:
#define BUTTONCALLBACK(Func) bind1st( mem_fun( &ClassICanSupport::Func ), this )
I can then create a button like this:
Button* b = new Button("Bla", BUTTONCALLBACK(functionIWanttoCall));
The Callback function has the following signature:
void callback(Button* source);
When I press the button I can execute the callback function which I passed.
I had a look at boost::bind but I couldn't really find a way to tackle the problem. Furthermore all my classes are derived from a class Object so I thought about a void* which I could convert to the right class with some typeid hack but I was unable to get it working. At the end I always had the problem that I couldn't completly eliminate the class type of the callback function (which would be necessary to save the function pointer in my button class) and still being able to call the function.
Do you have any idea how to tackle this problem?
Don't use pointers, use boost::function together with boost::bind (or std::function and std::bind if C++0x), something like
// in Button class (or whatever signature you need)
Button(const std::string&, boost::function<void(Button*)> callback) // ...
// you can then use callback as a function
// in calling code
Button *b = new Button("..", boost::bind(&Class::func, this));
You should use a function<void(Button*)> object. These are run-time polymorphic and can be used with any object that supports void operator()(Button*). You can find one in Boost, TR1 and C++0x. boost::bind works well with these objects.
Well, the easiest way would be with virtual functions, if you don't want to pull in Boost or don't have access to C++0x.
#include <iostream>
// fwd declare
class Button;
class BtnCallbackBase{
public:
virtual void operator()(Button*) = 0;
};
template<class C>
class BtnCallback : public BtnCallbackBase{
private:
typedef void (C::*callback_func)(Button*);
C* _object;
callback_func _onclick;
public:
BtnCallback(C* obj, callback_func func)
: _object(obj)
, _onclick(func)
{}
virtual void operator()(Button* btn){
(_object->*_onclick)(btn);
}
};
class Button{
public:
Button()
: _onclick(0)
{}
void Click(){
if(_onclick != 0)
(*_onclick)(this);
}
template<class C>
void RegisterCallback(C* obj, void (C::*func)(Button*)){
// cleanup old callback, deleting null pointer is a noop
delete _onclick;
_onclick = new BtnCallback<C>(obj,func);
}
~Button(){
delete _onclick;
}
private:
BtnCallbackBase* _onclick;
};
class MyClass{
public:
void ExampleCallback(Button* btn){
std::cout << "Callback works!\n";
}
};
int main(){
Button btn;
MyClass test;
btn.RegisterCallback(&test, &MyClass::ExampleCallback);
btn.Click();
}
Full example on Ideone.
If you want a solution to your problem without using Boost library / without using new C++ features then one of the best choice is Generic Callbacks Dispatcher discussed by Danny Kalev / Herb Sutter.
http://www.gotw.ca/gotw/083.htm

How to pass a Function pointer without exposing class details

I'm creating a library that needs to allow the user to set a callback function.
The interface of this library is as below:
// Viewer Class Interface Exposed to user
/////////////////////////////
#include "dataType_1.h"
#include "dataType_2.h"
class Viewer
{
void SetCallbackFuntion( dataType_1* (Func) (dataType_2* ) );
private:
dataType_1* (*CallbackFunction) (dataType_2* );
}
In a typical usage, the user needs to access an object of dataType_3 within the callback.
However, this object is only known only to his program, like below.
// User usage
#include "Viewer.h"
#include "dataType_3.h"
// Global Declaration needed
dataType_3* objectDataType3;
dataType_1* aFunction( dataType_2* a)
{
// An operation on object of type dataType_3
objectDataType3->DoSomething();
}
main()
{
Viewer* myViewer;
myViewer->SetCallbackFunction( &aFunction );
}
My Question is as follows:
How do I avoid using an ugly global variable for objectDataType3 ?
(objectDataType3 is part of libraryFoo and all the other objects dataType_1, dataType_2 & Viewer are part of libraryFooBar) Hence I would like them to remain as separate as possible.
Don't use C in C++.
Use an interface to represent the fact you want a notification.
If you want objects of type dataType_3 to be notified of an event that happens in the viewer then just make this type implement the interface then you can register the object directly with the viewer for notification.
// The interface
// Very close to your function pointer definition.
class Listener
{
public: virtual dataType_1* notify(dataType_2* param) = 0;
};
// Updated viewer to use the interface defineition rather than a pointer.
// Note: In the old days of C when you registered a callback you normally
// also registered some data that was passed to the callback
// (see pthread_create for example)
class Viewer
{
// Set (or Add) a listener.
void SetNotifier(Listener* l) { listener = l; }
// Now you can just inform all objects that are listening
// directly via the interface. (remember to check for NULL listener)
void NotifyList(dataType_2* data) { if (listener) { listener->notify(data); }
private:
Listener* listener;
};
int main()
{
dataType_3 objectDataType3; // must implement the Listener interface
Viewer viewer;
viewer.SetNotifier(&objectDataType3);
}
Use Boost.Function:
class Viewer
{
void SetCallbackFuntion(boost::function<datatype_1* (dataType_2*)> func);
private:
boost::function<datatype_1* (dataType_2*)> CallbackFunction;
}
Then use Boost.Bind to pass the member function pointer together with your object as the function.
If you don't want or can't use boost, the typical pattern around callback functions like this is that you can pass a "user data" value (mostly declared as void*) when registering the callback. This value is then passed to the callback function.
The usage then looks like this:
dataType_1* aFunction( dataType_2* a, void* user_ptr )
{
// Cast user_ptr to datatype_3
// We know it works because we passed it during set callback
datatype_3* objectDataType3 = reinterpret_cast<datatype_3*>(user_ptr);
// An operation on object of type dataType_3
objectDataType3->DoSomething();
}
main()
{
Viewer* myViewer;
dataType_3 objectDataType3; // No longer needs to be global
myViewer->SetCallbackFunction( &aFunction, &objectDataType3 );
}
The implementation on the other side only requires to save the void* along with the function pointer:
class Viewer
{
void SetCallbackFuntion( dataType_1* (Func) (dataType_2*, void*), void* user_ptr );
private:
dataType_1* (*CallbackFunction) (dataType_2*, void*);
void* user_ptr;
}
boost::/std:: function is the solution here. You can bind member functions to them, and in addition functors and lambdas, if you have a lambda compiler.
struct local {
datatype3* object;
local(datatype3* ptr)
: object(ptr) {}
void operator()() {
object->func();
}
};
boost::function<void()> func;
func = local(object);
func(); // calls object->func() by magic.
Something like this is simple to do:
class Callback
{
public:
virtual operator()()=0;
};
template<class T>
class ClassCallback
{
T* _classPtr;
typedef void(T::*fncb)();
fncb _cbProc;
public:
ClassCallback(T* classPtr,fncb cbProc):_classPtr(classPtr),_cbProc(cbProc){}
virtual operator()(){
_classPtr->*_cbProc();
}
};
Your Viewer class would take a callback, and call it using the easy syntax:
class Viewer
{
void SetCallbackFuntion( Callback* );
void OnCallCallback(){
m_cb->operator()();
}
}
Some other class would register the callback with the viewer by using the ClassCallback template specialization:
// User usage
#include "Viewer.h"
#include "dataType_3.h"
main()
{
Viewer* myViewer;
dataType_3 objectDataType3;
myViewer->SetCallbackFunction( new ClassCallback<dataType_3>(&objectDataType3,&dataType_3::DoSomething));
}
You're asking several questions mixed up in here and this is going to cause you lots of confusion in your answers.
I'm going to focus on your issue with dataType_3.
You state:
I would like to avoid declaring or
including dataType_3 in my library as
it has huge dependencies.
What you need to do is make an interface class for dataType_3 that gives the operations -- the footprint -- of dataType_3 without defining everything in it. You'll find tips on how to do that in this article (among other places). This will allow you to comfortably include a header that gives the footprint for dataType_3 without bringing in all of its dependencies. (If you've got dependencies in the public API you may have to reuse that trick for all of those as well. This can get tedious, but this is the price of having a poorly-designed API.)
Once you've got that, instead of passing in a function for callback consider having your "callback" instead be a class implementing a known interface. There are several advantages to doing this which you can find in the literature, but for your specific example there's a further advantage. You can inherit that interface complete with an instantiated dataType_3 object in the base class. This means that you only have to #include the dataType_3 interface specification and then use the dataType_3 instance provided for you by the "callback" framework.
If you have the option of forcing some form of constraints on Viewer, I would simply template that, i.e.
template <typename CallBackType>
class Viewer
{
public:
void SetCallbackFunctor(CallBackType& callback) { _callee = callback; }
void OnCallback()
{
if (_callee) (*_callee)(...);
}
private:
// I like references, but you can use pointers
boost::optional<CallBackType&> _callee;
};
Then in your dataType_3 implement the operator() to do as needed, to use.
int main(void)
{
dataType_3 objectDataType3;
// IMHO, I would construct with the objectDataType3, rather than separate method
// if you did that, you can hold a direct reference rather than pointer or boost::optional!
Viewer<dataType_3> viewer;
viewer.SetCallbackFunctor(objectDataType3);
}
No need for other interfaces, void* etc.

Function pointer to class member function problems

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.
Your private member method has an implicit this pointer as first argument. If you write that out, it's obvious that the function signatures do not match.
You need to write a static member function, which can be passed as the callback-function to the library. The last argument to the HookFunction, a void*, looks to me very much like a cookie, where one can pass ones own pointer in.
So, all in all, it should be something like this:
class MyClass {
long MyCallback(long, long) {
// implement your callback code here
}
static long __stdcall ThirdPartyGrabCallback(long a, long b, void* self) {
return reinterpret_cast<MyClass*>(self)->MyCallback(a, b);
}
public:
void StartGrab() {
ThirdPartyGrab(..., &MyClass::ThirdPartyGrabCallback, ..., this, ...);
}
};
This of course only works if the void* argument is doing what I said. The position of the this in the ThirdPartyGrab() call should be easy to find when having the complete function signature including the parameter names available.
The reason "&MyFrameGrabber::HookFunction" cannot be converted to a BUF_HOOK_FUNCTION_PTR is that, being a member of the class, it has implicitly as first parameter the "this" pointer, thus you cannot convert a member function to a non-member function: the two signatures look the same but are actually different.
I would declare an interface, defining the function to call, have your class implement it and pass the object itself instead of the callback (you can think of an interface as the object-oriented replacement of a function pointer):
class IHookInterface{
public:
virtual long HookFunction(long, long, void*) = 0;
};
class HookClass : public IHookInterface{
public:
virtual long Hook(long, long, void*) {
// your code here...
}
};
// new definition:
ThirdPartyGrab (..., IHookInterface, ...);
EDIT - other possible solution in case you cannot modify the library: use a singleton rather than a static function.
class HookClass{
public:
static HookClass& instance(){
static HookClass _instance;
return _instance;
}
long Hook(long, long, void*) {
// your code here...
}
};
long call_hook(long x,long y,void * z){
return HookClass::instance().Hook(x,y,z);
}
SECOND EDIT: you might slightly modify the singleton class with an initialization method to call the constructor with the proper parameters, but maybe it is not more elegant than the following solution, which is simpler:
class HookClass{
public:
HookClass(string x,string y...){
}
long Hook(long, long, void*) {
// your code here...
}
};
static HookClass * hook_instance = 0;
long call_hook(long x,long y,void * z){
if (0 != hook_instance){
return hook_instance->Hook(x,y,z);
}
}
int main(){
hook_instance = new HookClass("x","y");
ThirdPartyGrab(..., call_hook, ...);
}