[英]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.