Arduino MQTT库如何将类成员函数作为onMessageAdvanced的回调传入
问题原因
普通非静态类成员函数存在隐式this指针参数,实际的函数签名和回调要求的std::function<void(MQTTClient *client, char topic[], char bytes[], int length)>不匹配,因此无法直接作为参数传入。
解决方案
因为该库的回调接口支持std::function类型,你可以用捕获类实例的lambda表达式做一层转接,不需要修改原有成员函数的逻辑。
关键修改点
把setup函数中设置回调的代码:
ple.client.onMessageAdvanced(&ple.messageReceived);
替换为:
ple.client.onMessageAdvanced([&ple](MQTTClient *client, char topic[], char bytes[], int length) { // 转发到类的成员函数 ple.messageReceived(client, topic, bytes, length); });
更优的封装方式
你也可以把回调设置逻辑放到类内部,封装性更好:
在MyClass里新增一个初始化方法,或者直接写在connect逻辑里:
void MyClass::init(const char* mqtt_server, WiFiClient& net) { client.begin(mqtt_server, net); // 类内部直接捕获this即可 client.onMessageAdvanced([this](MQTTClient *client, char topic[], char bytes[], int length) { this->messageReceived(client, topic, bytes, length); }); }
对应的setup里就改成调用ple.init("192.168.1.23", ple.net);即可。
其他可选方案
如果你不想用lambda,也可以把messageReceived声明为静态成员函数,但静态成员函数无法直接访问类的非静态成员,需要额外存储类实例指针才能操作类的其他属性,灵活性不如lambda方案。
内容的提问来源于stack exchange,提问作者sarah.ferguson
相关产品推荐
相关产品推荐

