【发布时间】:2018-02-13 00:28:00
【问题描述】:
我一直在研究如何使用 lambdas 作为回调,但我的语法似乎并不正确。我正在通过 Visual Studio 2013 Community 在 C++ 中工作,并且我很确定这种类型的 lambda 使用是受支持的。我正在开发一个基于 FFMPEG libav 库的视频库。
基本问题是提供给 FFMPEG 的 libav 库客户端的日志记录回调。它有这样的调用结构:
void logging_callback( void *ptr, int level, const char *fmt, va_list vargs );
当日志回调是静态成员函数时,这对 C 或 C++ 都很好,但我想安装一个类成员函数,根据 C++ 调用的性质,它需要 this 参数方法函数。
我目前的样子:(不相关的部分已删除)
class my_libav
{
// logging messages callback for use by library client, any log messages generated
// by the library will be sent thru this to the lib client's logic:
typedef void(*STREAM_LOGGING_CALLBACK_CB) (std::string msg, void* p_object);
// my lib's logger has a void* param so clients can redirect to member functs easier
void SetStreamLoggingCallback(STREAM_LOGGING_CALLBACK_CB p_stream_logger, void* p_object);
// member function to be installed as FFMPEG's av_log_set_callback():
void RedirectLoggingOutputs( void *ptr, int level, const char *fmt, va_list vargs );
STREAM_LOGGING_CALLBACK_CB mp_stream_logging_callback; // client's callback
void* mp_stream_logging_object; // client's data
};
void my_libav::SetStreamLoggingCallback(STREAM_LOGGING_CALLBACK_CB p_stream_logger, void* p_object)
{
mp_stream_logging_callback = p_stream_logger;
mp_stream_logging_object = p_object;
}
void my_libav::RedirectLoggingOutputs(void *ptr, int level, const char *fmt, va_list vargs )
{
// logic that resolves the message and sends through client's callback
// installed int mp_stream_logging_callback
}
my_libav::my_libav()
{
// this is the old static member function I deleted:
// av_log_set_callback( &my_libav::logging_callback );
// I tried using std::bind & placeholders, but this syntax is wrong too:
// namespace ph = std::placeholders;
// auto callback = std::bind( &my_libav::RedirectLoggingOutputs, this, ph::_1, ph::_2, ph::_3, ph::_4 );
//
// av_log_set_callback( callback ); // <- 'callback' is not the correct type
// this is my try at a lambda. I know that the *this* cannot be
// in the capture, but I don't know the right syntax to work around
// this issue:
std::function<void(void *ptr, int level, const char *fmt, va_list vargs )>
f2 = [this](void *ptr, int level, const char *fmt, va_list vargs ){
RedirectLoggingOutputs( ptr, level, fmt, vargs ); };
av_log_set_callback( f2 ); // <- 'f2' is not the correct type, how to fix?
我要修复的语法在最后 4 行。正确的形式是什么?
【问题讨论】:
-
我不确定如何使用全局变量或 TLS 存储来实现。我看不出如何使用全局变量来完成;但在 TLS 的情况下,是否会创建一个仅处理此回调的单独类?然后 my_lib 的构造函数在这个 callback_redirecting_class 上执行“new”,它使用 TLS 保存/隐藏指向创建 callback_redirecting_class 实例的类的“this”指针?
标签: c++ lambda ffmpeg callback