问题描述
我想将 c ++ objcet成员回调func 传递给“ c” lib ,该文件仅具有void *。然后,我使用std :: function注册回调处理程序。但是当我将std :: function *转换为void *时出现问题,似乎std :: function *在转换为void *时被破坏了。
下面是测试代码。
#include <iostream>
#include <functional>
class TfLight {
public:
void print(int a) {
std::cout << "TfLight::print " << a << std::endl;
}
};
class Server {
public:
void run(int a) {
std::function<void(int)>* func = reinterpret_cast<std::function<void(int)>*>(ptr);
std::cout << func << std::endl;
(*func)(a);
}
void register(std::function<void(int)> tf) {
std::cout << (&tf) << std::endl;
// f = tf;
setPtr(&tf);
}
void setPtr(void* p) {
ptr = p;
}
std::function<void(int)> f;
void* ptr;
};
int main()
{
TfLight* tf = new TfLight();
Server* server = new Server();
server->register(std::bind(&TfLight::print,tf,std::placeholders::_1));
server->run(3333);
delete server;
delete tf;
}
当我使用全局变量保存“ std :: function
但是当我将std :: function *转换为void *时出现问题,似乎std :: function *在转换为void *时被破坏了
解决方法
std::bind
是一个函数。它不在堆栈或堆中。
其返回值是一个临时对象,并且具有通常的临时寿命。这不是这里的问题。返回值bind
存储在传递给std::function
的{{1}}中。
在register
中,再次遵循常规的C ++规则。 register
是一个函数参数,因此std::function<void(int)> tf)
在调用期间一直有效。 &tf
返回后,register
便不复存在。注释掉的代码是正确的;您应该已经将其复制到tf
。
由于您拥有Server::f
,因此Server::f
似乎毫无意义。是的,您可以将void* Server::ptr
设置为ptr
,但是为什么呢?