将 c++ lambda 传递给 C 函数
Passing c++ lambda to C functions
我正在尝试在libuv上包装一个C++层,并将lambda用于回调函数。然而,gcc 出错了。
这是缩小版本:
#include <uv.h>
class Test {
public:
void on_conn(uv_stream_t *server, int status) { }
void test() {
uv_tcp_t server;
auto err = uv_listen((uv_stream_t*)&server,
100,
[this] (uv_stream_s *server, int status) -> void {
this->on_conn(server,status);
});
}
};
Test t;
libuv中的相关声明是:
# define UV_EXTERN /* nothing */
struct uv_stream_s { ... };
typedef struct uv_stream_s uv_stream_t;
typedef void (*uv_connection_cb)(uv_stream_t* server, int status);
UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb);
错误 g++ 给出:
$ g++ --version
g++ (GCC) 6.1.1 20160501
<<--ERROR--{reformatted}-->>
t.cpp:15:7: error: cannot convert
‘Test::test()::<lambda(uv_stream_s*, int)>’ to
‘uv_connection_cb {aka void (*)(uv_stream_s*, int)}’
for argument ‘3’ to ‘int uv_listen(uv_stream_t*, int, uv_connection_cb)’
}));
这里到底坏了什么?有什么方法可以做到这一点吗?
更新:
更有趣.. 这在 lambda 的主体中做了一些事情 ; 第一次调用有效,第二次调用无效。
int cfunc( void cb() );
class Test {
public:
void d(){}
void test() {
cfunc( [=] () {});
cfunc( [=] () { this->d(); });
//cfunc( [this] () { });
//cfunc( [&this] () { });
}
};
t.cpp:10:34: error: cannot convert ‘Test::test()::<lambda()>’ to ‘void (*)()’ for argument ‘1’ to ‘int cfunc(void (*)())’
cfunc( [=] () { this->d(); });
捕获 lambda 不能转换为函数指针,只有非捕获可以:
//Lambda captures 'this', and so cannot be converted to function pointer
[this](uv_stream_s *server, int status) -> void {
this->on_conn(server,status);
}
也许您可以使用如下所示的技巧:
class Test;
struct my_uv_tcp_t: uv_tcp_t {
Test *test;
};
class Test {
public:
Test(): server{} { server.test = this; }
void on_conn(uv_stream_t *server, int status) { }
static void cb(uv_stream_t *server, int status) {
auto srv = static_cast<my_uv_tcp_t*>(server);
srv->test->on_conn(server, status);
}
void test() {
auto err = uv_listen((uv_stream_t*)&server, 100, Test::cb);
}
private:
my_uv_tcp_t server;
};
一旦流上发生某些事情,它就会被返回,它的句柄只不过是一个裸指针。
您可以使用同一流来存储控制器(在本例中为 Test
类的实例)的信息,并在收到流时将其转换为其原始形式。
否则,如果 data
字段仍未使用,请使用作为句柄一部分
它应该是工作。我遇到了同样的问题,所以我通过句柄对象属性将当前对象发送到 lambda。
#include <uv.h>
class Test {
public:
void on_conn(uv_stream_t *server, int status) { }
void test() {
uv_tcp_t server;
server.data = this;
auto err = uv_listen((uv_stream_t*)&server,
100,
[] (uv_stream_s *server, int status) -> void {
auto self = (Test*)server->data;
self->on_conn(server,status);
});
}
};
Test t;
相关文章:
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗