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:
#include <stdio.h>
#include <functional>
#include <thread>
void register_with_library(int (*func)(int *k, int *e)) {
int x = 0, y = 1;
int o = func(&x, &y);
}
typedef int (*callback_t)(int*,int*);
class A {
template <typename T>
struct Callback;
template <typename Ret, typename... Params>
struct Callback<Ret(Params...)> {
template <typename... Args>
thread_local static Ret callback(Args... args) {
func(args...);
}
thread_local static std::function<Ret(Params...)> func;
};
public:
A();
~A();
int e(int *k, int *j);
private:
callback_t func;
};
template <typename Ret, typename... Params>
thread_local std::function<Ret(Params...)> A::Callback<Ret(Params...)>::func;
A::A() {
Callback<int(int*,int*)>::func = std::bind(&A::e, this, std::placeholders::_1, std::placeholders::_2);
printf("1. C callback function ptr %p, C++ template function ptr %p Object ptr %p
",func, Callback<int(int*,int*)>::func, this) ;
func = static_cast<callback_t>(Callback<int(int*,int*)>::callback);
printf("2. C callback function ptr %p
",func) ;
register_with_library(func);
}
int A::e(int *k, int *j) {
return *k - *j;
}
A::~A() { }
int main() {
std::thread t1 = std::thread { [](){ A a;}};
std::thread t2 = std::thread { [](){ A a;}};
t1.join();
t2.join();
}
The result is
function ptr 0x400eef
function ptr 0x400eef
How would one make this work properly to create new callbacks for each new object, considering I have multiple threads creating different objects?
EDIT:
As suggested by e.jahandar, using thread_local works to partially resolve the issue (only if there is 1 object created per thread). Thanks to this, Callback<int(int*,int*)>::func
is allocated on a thread basis. Although, the issue persists with Callback<int(int*,int*)>::callback
.
Without thread_local:
1. C callback function ptr 0x403148, C++ template function ptr 0x609180 Object ptr 0x7ff9ac9f3e60
2. C callback function ptr 0x403673
1. C callback function ptr 0x4031a6, C++ template function ptr 0x609180 Object ptr 0x7ff9ad1f4e60
2. C callback function ptr 0x403673
with thread_local :
1. C callback function ptr 0x403230, C++ template function ptr 0x7fc1ecc756d0 Object ptr 0x7fc1ecc74e20
2. C callback function ptr 0x403701
1. C callback function ptr 0x4031d2, C++ template function ptr 0x7fc1ec4746d0 Object ptr 0x7fc1ec473e20
2. C callback function ptr 0x403701
See Question&Answers more detail:
os