0

I am programming against an external library which requires a static callback function. I declared my callback as static but then i loose access to the object properties i want to modify with this callback.

.h
static void selCallback(void* userData, SoPath* selPath);

.cpp
void MyClass::selCallback(void* userData, SoPath* selPath) {
    classProperty = 3;
}

Is there a way how can create a static callback while being able to access my current objects properties? The library i use is the openInventor library. The callback wiring up is done with the following code:

SoSelection *selNode = new SoSelection;
selNode->addSelectionCallback(MyClass::selCallback);
narain
  • 392
  • 5
  • 18
  • `userData` may be reserved for this purpose. To be checked but `MyClass* obj = static_cast(userData)` can give you an access to `obj->classProperty`. You should inspect the calls of your callback function to know if and how the object is passed. – Franck Nov 14 '16 at 13:17
  • 1
    _Is there a way how can create a static callback while being able to access my current objects properties?_ Well.. That's the reason why you aren't able to access non-static properties/methods from a static context. Static methods/properties are common for all instances of a class, and you may have hundreds of instances created. So, how do you decide, what is _current object_ from a static context? How it's typically done, is to pass a pointer to the object, to the static method. Then, you can access the properties of the object, that you are interested in. – Algirdas Preidžius Nov 14 '16 at 13:17

2 Answers2

1

Usually there is some place where the void* userData can be specified, either when creating the library object or when registering the callback. You can set this to a pointer to the object you want to access from the callback. Then inside the callback you cast the void* pointer back to a pointer to your class and manipulate it through that.

This way you can't use C++ smart pointers, so you'll have to take care of object lifetimes yourself.

Waldheinz
  • 10,399
  • 3
  • 31
  • 61
1

The addSelectionCallback method has an optional parameter for userData pointer. There you should send the object instance, which you will receive then in your callback.

Inside the method, you can typecast to the correct object type and do the actual work with the object instance.

For example:

void MyClass::selCallback(void* userData, SoPath* selPath) {
    static_cast<MyClass *>(userData)->classProperty = 3;
}

MyClass myInstance;
selNode->addSelectionCallback(MyClass::selCallback, &myInstance);
EmDroid
  • 5,918
  • 18
  • 18