c - 在 C++ 中无状态地包装 C 回调接口
问题描述
我需要在 C++ 中无状态地包装 C 接口的回调机制,以接受可调用对象,即包装类不应有任何非 const 成员。在 C 接口中(不在我的控制之下)有一个添加回调的函数:
void c_add_callback(void(*callback)(void* context), void* context)
这是我尝试将 C 接口包装在一个接受对可调用对象的引用的类中:
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_;
};
显然,这种方法不是无状态的,因为我必须将回调(成员 c_callbacks_)存储为传递给 C 接口,否则传递给 c_add_callbacks 的 lambdas 将是临时的,并且会在 c_add_callback 返回时被破坏,请参阅Casting a universal reference to可调用 void 指针,反之亦然
有没有办法实现包装类无状态,即摆脱成员?
有关完整代码示例,请参阅https://onlinegdb.com/rkeh-UNX0U。
一些背景: 使包装器无状态的意图来自于 C 接口背后的库可能在某些时候处理所有添加的回调的事实。显然,当循环添加回调并触发库处理它们时,这将导致列表不断增长(成员 c_callbacks_)。如果 dispose 操作没有通过 C 接口传播,我该如何处理这种泄漏?
解决方案
我根本不理解你想要达到什么目的c_callbacks_
。c_callbacks_.back()
您只在, 之后直接使用它c_callbacks_.push_back()
只需使用
c_add_callback([](void* context)
{
(*reinterpret_cast<Function*>(context))();
},
reinterpret_cast<void*>(&function));
注意:与您的示例一样,这假设 的生命周期&function
是外部管理的。
推荐阅读
- java - Java Spring Security WebClient 与 ServerOAuth2AuthorizedClientExchangeFilterFunction 一起使用时抛出 SSLHandshakeException
- python - 如何使用 .dat 文件中的某些数据附加列表?
- swift - Swift 中的目录不一致
- windows - 缺少 WUAPI Windows 10 功能更新下载 URL
- data-structures - 用于拓扑排序的卡恩算法的时间复杂度
- reactjs - 使用 useReducer 更新状态
- python - 获取 ValueError:列的长度必须与键的长度相同
- macos - AppleScript:获取窗口的上下文菜单
- c# - Unity生成Cube中的内存不足异常将立方体的每个面细分4次
- reactjs - React中textarea中滚动条的边框半径问题