The original question, got a great answer as to how to do the non thread safe version.
Here is the code, which I\'ve tried to slightly modify to get to work:
<
If each thread just need one instance of specific object, you can use a global variable for object pointer with __thread storage class, __thread makes global variables unique to that thread.
Using monotonic class with static member for callback is another solution, like previous solution, you can use __thread for separating monothonic class instances for each thread.
Also be aware, __thread isn't standard thing
Edit
Here is an example
class.h
class someClass{
private:
someMethod(){ ... }
}
class.cpp
__thread void * objectPointer;
void initialize(){
someClass * classPtr = new someClass();
objectPointer = (void *) classPtr;
}
void * callbackFunction(void * args){
someClass * obj = objectPointer;
obj->someMethod();
}
The only standards compliant way to make a C++ function callable from C is to declare it with C linkage.
extern "C" int my_callback_wrapper (A*, int*, int*);
my_callback
can be neither template, nor a member function (even static).
Anything beyond that is undefined behaviour.
In order to be standards-compliant, you have to manually wrap every single class member function with a separate callback wrapper. This solution is naturally thread safe as it doesn't use any global or static data.
Naturally it requires the C code to obtain pointer(s) to your A object(s), and pass the right pointer to the callback at the right moment. Hiding an instance of A
from the C library amounts to storing A in some static/global storage, which means there can be only one per callback. If you are using C++11, you can also specify thread_local storage and have an object per thread.
extern "C" int my_callback_wrapper (int* x, int* y);
thread_local A* aptr = nullptr;
thread_local int (A::*fptr)(int*, int*) = nullptr;
void register_cxx_callback (A* a, int (A::*f)(int*, int*))
{
if (aptr != nullptr || fptr != nullptr)
fatal_error ("Trying to overwrite the callback!");
aptr = a;
fptr = f;
register_with_library(my_callback_wrapper);
}
extern "C" int my_callback_wrapper (int* x, int* y)
{
if (aptr == nullptr || fptr == nullptr)
fatal_error ("Callback is called but the object is not registered!");
printf ("aptr is %p\n", (void*)aptr);
return (aptr->*fptr)(x, y);
}
A full working example is here.
This solution is also thread safe as long as the C library doesn't attempt to pass registered callbacks between threads. It is also standards compliant, as far as I can tell.
There are no templates because there are no C linkage templates. One can enclose the static/thread-local data in an class, but I don't see much point in classes that only have static data.
There is no way to portably register an arbitrary number of objects per thread. In the end, you have to provide a C function pointer, and C functions cannot portably have hidden arbitrary data (IOW you cannot build closures in standards compliant C). If you are interested in a non-portable solution, there is a library that does that.