繁体   English   中英

WifiClient问题-必须是有关局部变量和全局变量的基本C / C ++问题

[英]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 = &param;
    }
    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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM