将函子/lambdas与C回调一起使用
Using functors/lambdas with C callbacks
我正在为一个流行的开源C库编写一个C++11包装器,提供RAII和您所期望的所有其他细节。包装器将仅为头(因此只需要链接到原始的C库),此外,我想坚持的原则之一是包装器应尽可能"零开销",也就是说,当启用优化时,所有内容都应内联,以便只保留C函数调用。
在大多数情况下,这并没有那么困难:正如你所期望的那样,我有一些类持有指向(不透明)C类型的指针,有调用"create"函数的构造函数、调用"destroy"功能的析构函数、调用C函数的方法等。到目前为止,很容易。
然而,我遇到的一个问题是如何处理回调。图书馆有几个形式的入口点
typedef <function signature> CallbackType;
void set_callback(CallbackType cb, void* data);
使得底层C库将cb
和data
存储在静态变量中,并且当发生特定事件时,触发回调,并将data
与其他参数一起传递回它。
我想提供包装器,以便任何C++可调用的(即函数、函子、lambdas、使用std::bind
的方法调用等)都可以在回调中使用。然而,函子和(捕获)lambdas是需要存储在某个地方的对象,以确保它们在触发回调时仍然有效。确切地把它们存放在哪里似乎有问题。。。我不能把它们放在堆上,因为它们不能被删除,而且我不能(容易地)使用静态变量,因为我的库只有头。
有人有什么建议/巧妙的想法/技巧可以在这种情况下使用吗?
提前谢谢。
致下午,如果你看到这一点:为前几天的混乱道歉,我在工作时间发布了这个关于个人项目的问题,所以我觉得最好删除它,当时它只有5次浏览,所以我认为我逃脱了惩罚,但显然不是。如果你不介意再打一次,我会对你的答案感兴趣吗
将订阅句柄和回调对象放在单个订阅包装器中。然后,用户有责任保留这个包装器,只要他想从你的c库获得回调。
class subscription
{
std::function<void(int)> m_f;
static void callback(int param, void* data)
{
static_cast<subscription*>(data)->m_f( param );
}
subscription( const subscription& other ) = delete;
subscription& operator=( const subscription& ) = delete;
public:
subscription( const std::function<void(int)>& f ) : m_f(f)
{
set_callback( &callback, this);
}
~subscription()
{
clear_callback(&callback, this);
}
};
用法:
subscription s( [](int param){ std::cout<<param*2<<std::endl; } );
相关文章:
- 架构决策:返回std::future还是提供回调
- 正在为Xtensa simcall函数编写回调函数
- 如何在C++中使用非静态成员函数作为回调函数
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 用于在回调中调用解析器的设计模式
- 如何使用C++对象的成员函数作为 C 样式回调?
- Java从C++回调到C++回调
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 从不同的 cpp 调用回调函数会导致bad_function_call
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- 不带轮询的 SDL2 事件回调
- C++存储带有可变参数的回调
- 如何使用 Node-addon-API 实现 node-nan 回调
- MSVC __debugbreak() 与 openGL 错误回调一起使用时不会产生调用堆栈
- 如何定义与将 Lambda 与捕获作为回调一起使用兼容的函数指针
- libcurl进度回调无法与Multi一起使用
- Boost Asio和Co_await-与任何第三方回调一起使用
- 将libuv与函数结构一起使用,而不是函数回调
- 将函子/lambdas与C回调一起使用