C++如何正确将类成员函数赋值给非类类型的回调函数变量
报错根本原因
- 非静态类成员函数存在隐藏的
this指针参数
你定义的CMQTT::local_mqtt_callback是类的非静态成员函数,C++中这类函数会被编译器自动添加一个隐藏的第一个参数,指向当前类实例的this指针。你写的函数签名看起来是void(MQTTClient*, char*, char*, int),但实际编译器处理后的真实签名是void(CMQTT*, MQTTClient*, char*, char*, int),和该MQTT库要求的回调函数签名完全不匹配,直接传非静态成员函数肯定会触发类型不匹配的编译错误。 - 标准库绑定工具返回的可调用对象和原生C函数指针类型不兼容
你尝试使用的std::bind、std::mem_fun、std::bind2nd这些工具,返回的都是携带状态的函数对象(可调用对象),而该MQTT库的onMessageAdvanced接口要求传入的是无状态的原生C风格函数指针,二者类型不匹配。就算你把bind的语法写对(你写的std::bind(&CMQTT::local_mqtt_callback),this)本身就存在括号配对错误,正确写法应该是std::bind(&CMQTT::local_mqtt_callback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)),返回的函数对象也不能隐式转换为库要求的函数指针类型,依然会编译报错。 - 静态成员函数生效的原因
静态类成员函数属于类本身,不会被添加隐藏的this指针参数,签名和普通C函数完全一致,所以可以直接匹配库要求的函数指针类型,因此声明为static就可以解决问题。如果需要在回调中访问类实例的非静态成员,可以额外定义一个静态的类实例指针,在初始化时赋值,静态回调中通过这个静态指针访问实例成员即可。
内容的提问来源于stack exchange,提问作者user8888824
相关产品推荐
相关产品推荐

