[英]WifiClient issue - must be a basic C/C++ problem regarding local vs. global variables
在下面的代码中,执行mqtt.publish()时会崩溃,但这仅在wificlient是局部变量的情况下才会发生-如果wificlient是全局变量,则问题就消失了。
我认为并不需要了解底层库。
关于指针/垃圾回收必须有一些细微之处,否则会导致这种情况。 我已经从事C#多年了,对C ++的经验却少得多。
#include <PubSubClient.h>
#include <WiFiClient.h>
void mqttSubs(char* topic, byte* payload, unsigned int length) {}
// if this line is moved inside setup() then the call to publish will crash
WiFiClient wifiClientGlobal;
PubSubClient mqttClient;
void setup() {
//WiFiClient wifiClientGlobal;
mqttClient = PubSubClient(mqttServer, mqttPort, mqttSubs, wifiClientGlobal);
mqttClient.connect("ESP8266Client", mqttUser, mqttPassword );
}
void loop() {
mqttClient.publish("repro/global", "sending message");
}
谁能阐明这一点?
没有太多的转租,只是(imo)错误的文档和PubSubClient上的优化API。
PubSubClient构造函数采用对客户端的引用。
PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
然后获取指向它的指针以将其存储为成员。
这意味着它希望引用的Client
实例的PubSubClient
超过PubSubClient
实例的PubSubClient
。
没有垃圾收集发生。 只是如果您声明一个具有自动存储持续时间的对象,那么当它超出范围时,它将被销毁。
因此,原因基本上是这样的:
struct B{
int num;
};
struct A{
A(B& param){
m_b = ¶m;
}
B* m_b;
};
A obj;
setup()
{
B b;
obj = A(b);
//after this function ends b is considered destroyed
}
loop()
{
//the following line accesses a member of the already destroyed object
print(obj.m_b->num);
}
这个测试用例表现出与您的代码基本相同的“免费使用后使用”(它可能不会崩溃,但确实包含相同的未定义行为)。
在我看来, PubSubClient
获取对客户端的引用并存储指针以供以后使用是一种错误的模式。 它应该使用指向客户端的指针,以使其更清楚地了解发生了这种情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.