Reputation: 377
I need to wrap a callback mechanism of a C interface statelessly in C++ accepting callables, i. e. the wrapper class shall not have any non-const members. In the C interface (not under my control) there is a function to add a callback:
void c_add_callback(void(*callback)(void* context), void* context)
Here is my attempt to wrap the C interface in a class accepting a reference to a callable:
class CppWrapper
{
public:
// C++ callable parameter
template<typename Function>
void AddCallback(Function& function)
{
c_callbacks_.push_back
([](void* context)
{
(*reinterpret_cast<Function*>(context))();
}
);
c_add_callback
(c_callbacks_.back()
, reinterpret_cast<void*>(&function)
);
}
private:
// storage of c callbacks
std::list<void(*)(void*)> c_callbacks_;
};
Obviously, this approach is not stateless, as I have to store the callbacks (member c_callbacks_) as passed to the C interface, otherwise the lambdas as passed to c_add_callbacks would be temporaries and would be destructed when c_add_callback returns, see Casting a universal reference to a callable to void pointer and vice versa
Is there a way to implement the wrapper class stateless, i. e. get rid of the member?
Please see https://onlinegdb.com/rkeh-UNX0U for the full code example.
Some background: The intention to make the wrapper stateless comes from the fact that the library behind the C interface may at some point dispose all added callbacks. Obviously this would lead to an ever growing list (member c_callbacks_) when cyclically adding callbacks and triggering the library to dispose them. How can I cope with such leak if the dispose action is not propagated over the C interface?
Upvotes: 1
Views: 149
Reputation: 179819
I'm not at all understanding what you are trying to achieve with c_callbacks_
. You only use it for c_callbacks_.back()
, directly after c_callbacks_.push_back()
Just use
c_add_callback([](void* context)
{
(*reinterpret_cast<Function*>(context))();
},
reinterpret_cast<void*>(&function));
Note: Like your example, this assumes the lifetime of &function
is managed externally.
Upvotes: 1