I have a C library here which I want to wrap in a C++ class. The library works asynchronous and needs to set an error handler. I know how to wrap an error handler in a static class function for a C library, but I am used to having something like a void *user_data pointer, where I can put this in to call a member function from the static thunk.
Is there a way to register the callback for a member function directly, as this library does not feature a pointer to some userdata?
You can wrap it in your own static function which is aware of some global (or static local) object on which it is to operate. You can even make this function a static method if want, but you can't call a method on an object without supplying an object on which it is to be called.
Edit : having thought about it for a while, maybe there is a way. You can essentially emulate thread-local storage by having a global collection of collections of states indexed by thread id. Within each thread-bound collection of states you can keep a stack/queue (depending on how the data are processed) of calling objects. The callback can look up the stored queue (because the callback knows the thread id in which it is running). This would allow you to force a single-threaded framework to operate on multiple streams of data.
I'm so confused
we know that all functions defined as global so we can call and use any function inside any block without passing it as argument
why we use Function callback concept while we can use a function inside any function without passing it
so why we use callback concept ?
For the same reason you use variables instead of constants.
Passing a callback to a function allow that function to call a different callback depending on how it was called.
Calling a function by name inside a function will always call that one function.
The call back concept means to provide some other function with a function to call when it needs something to be done, e.g. when an event happens. It also often means we can change the function to be called in run-time.
In this way, the knowledge of when to call what is not needed by the calling function. For example, a 3rd party library defines callbacks for the user's program to "plug-in" functionality into the library, or to be called when an event occurrs, a state is reached or an error occurrs and the library needs to know what to do about the error.
This is just a simple answer. Google around to find more information and see https://en.wikipedia.org/wiki/Callback_(computer_programming)
I extended the class wxFileSystemHandler to handle special protocols I use in my application. My implementation of wxFileSystemHandler::CanOpen() is called, recognizes the protocol and returns TRUE. But my implementation of wxFileSystemHandler::OpenFile() never gets called. I inspected the wxWidgets code and saw that the CanOpen() member function is called by the pointer that I registered. But when a call to OpenFile() is made they pass the pointer to a wxFileSystem::MakeLocal() member function that tries to get another pointer inside a hash map that, obviously, is not my instance.
Someone got a problem like this before?
Not sure what exactly are you doing, i.e. when do you expect your handler to be called, but in any case MakeLocal() is supposed to create a new instance of the same class if you mark the object as being dynamically creatable using wxRTTI macros and use the object as given otherwise. So if you really need the same object to be reused, you probably need to use wxDECLARE_ABSTRACT_CLASS() in its class. But OTOH why is it a problem to make a new instance?
I have the following problem.
I got a class PluginLoader which oversees loading of plugins. It divides sub-stages of work to other classes like Plugin. Plugin calls functions of PluginLoader in its processing. Let's call that function AddData. Here, PluginLoader has to check if the data it receives is duplicate. For that, it uses a ConflictResolver class. Now, my problem is how to make an object of ConflictResolver available to PluginLoader. There are 3 ways I see out of this.
Use a ConflictResolverFactory class and create an object of ConflictResolver for PluginLoader.
Pass a constructed ConflictResolver* to the PluginLoader via its constructor or a member function SetConflictResolver and store it in a member variable and use it later. Both ways have drawbacks. If I pass it in the constructor, I will have to throw if the pointer is NULL. And I can't use exceptions as it is the custom here. If I pass it via SetConflictResolver, there is no way that I can guarantee that that function will be actually called by the user. Or I will have to check whether the member ConflictResolver* is NULL everywhere I use it.
Pass a ConflictResolver & to PluginLoaders Load method where all the work will be done. In turn, Plugins Load method has to accept a ConflictResolver & as well (though it has no use for it) and pass that back to AddData where PluginLoader will be able to use it.
Third method is safer compared to second. However, I have to pass around a reference even when it is not used.
If the first method cannot be used, what is the best way to do this?
Apologies for the wall :wq!
You could pass a ConflictResolver& to the PluginLoader constructor. You can now guarantee that the object is not null.
io_iterator_t enumerator;
kern_return_t result;
result = IOServiceAddMatchingNotification(
mNotifyPort,
kIOMatchedNotification,
IOServiceMatching( "IOFireWireLocalNode" ),
serviceMatchingCallback,
(void *)0x1234,
& enumerator );
serviceMatchingCallback((void *)0x1234, enumerator);
if i declare serviceMatchinCallback as static then it works, but i do not want it to be static. Is there a way to pass it a non-static callback function?
Thank you
The prototype for IOServiceMatchingCallback is not compatible with a non-static class method (and technically is not compatible with a static class method either), so you are not going to be able to use that.
But luckily IOServiceAddMatchingNotification supports a context pointer (or as they call it, a refCon) which will allow you to create a thunk that does not rely on global data.
You need to define a callback with compatible linkage (i.e. extern "C"). This function will cast your refCon to your object pointer and then forward the call to your instance method:
extern "C"
void io_callback(void *refcon, io_iterator_t iterator)
{
myclass *c = static_cast<myclass *>(refcon);
c->real_callback(iterator);
}
Then, when you call IOServiceAddMatchingNotification, make sure to pass a pointer to your object for refCon (here I'm assuming you call IOServiceAddMatchingNotification from a member function and you have a this pointer):
result = IOServiceAddMatchingNotification(
mNotifyPort,
kIOMatchedNotification,
IOServiceMatching( "IOFireWireLocalNode" ),
serviceMatchingCallback,
this,
&enumerator );
You could keep it static, but use the userdata to store the this pointer in addition to whatever other userdata you want (by packing them into a structure, for example) and then call an object-specific callback from the static version by calling this->someCallback (where this is the pointer stored in the userdata, of course).
Not directly.
The non-static function pointer (known as a member function pointer) has a hidden 'this' parameter so the types don't match. The static function has no 'this' pointer.
To get around this, you need to be able to pass in a user data item which is the 'this' pointer of the object you want to use as a callback. Then, specify a static member that is passed the user data, converts it to a pointer to the class object and calls the non-static member on it.
Looking at the code you've posted, it's hard to tell if there is a user data object, possibly the last-but=one parameter.
No, a non-static member would expect an object, and the caller (call-backer) does not have and will not provide one.
No. Non-static methods need an object to operate on. If you were to merely pass the method you would also need some way to tell the function which object to call the method on.
A non-static function has an implicit this parameter, and thus would have the wrong signature for the callback.
Sorry, no easy way to avoid the jump island.
if you put this line in your constructor (or in any instance method) then you should be able to do this.instanceMethod() to refer to the instance method.
EDIT
I just noticed you are using the user space IOKit API, not the kext side, which makes this post irrelevant.
Assuming you are working within the OS X kernel, you actually can do this.
You can use the OSMemberFunctionCast macro to convert a member function pointer to a plain C function pointer, do note that it should be called with the first argument pointing to an instance of the class, eg.
IOServiceMatchingCallback mycb = OSMemberFunctionCast(IOServiceMatchingCallback,
&myclassinstance, &MyClass::cb_method);
result = IOServiceAddMatchingNotification(
mNotifyPort,
kIOMatchedNotification,
IOServiceMatching( "IOFireWireLocalNode" ),
mycb,
&myclassinstance,
&enumerator);