我想将c++ objcet 成员回调 func传递给一个只有 void*的“c” lib。然后我使用 std::function 来注册回调处理程序。但是当我将 std::function<>* 转换为 void* 时出现问题,似乎当转换为 void* 时 std::function<>* 被破坏了。
下面是测试代码。
#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;
}
Run Code Online (Sandbox Code Playgroud)
当我使用全局变量来持有“std::function<void(int)>”时,它可以正常调用。我该如何处理这个问题?
但是当我将 std::function<>* 转换为 void* 时出现问题,似乎 std::function<>* 在转换为 void* 时被破坏
std::bind是一个函数。它不在堆栈或堆上。
它的返回值是一个临时对象,并且具有通常的临时对象生命周期。这不是这里的问题;在bind返回值存储在std::function传递给register。
在 中register,再次遵循正常的 C++ 规则。std::function<void(int)> tf)是一个函数参数,因此&tf在调用期间保持有效。一register回来,tf就不复存在了。注释掉的代码是正确的;你应该把它复制到Server::f.
既然你有Server::f,这void* Server::ptr似乎完全没有意义。是的,您可以设置ptr为&f,但为什么呢?