[英]Handling of const char* on ESP32
我正在对 ESP32 进行一些 Spotify API 调用。 我对 C++ 还很陌生,虽然我似乎让它按照我想要的方式工作,但我想知道这是否是正确的方法/最佳实践,或者我是否只是幸运。 不管我读了多少,关于字符和指针的整个事情对我来说仍然很困惑。
我正在调用 Spotify API,获得 json 响应并使用 ArduinoJson 库对其进行解析。 该库将所有键和值作为const char*
返回。我用来在屏幕上显示它的库也采用const char*
。 我在将它转换为字符串之前让它工作,使用 getTitle() function 返回字符串并将其转换回屏幕上显示。 在我读到字符串效率低下且最好避免之后,我尝试减少转换步骤。
void getTitle()
{
// I cut out the HTTP request and stuff
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, http.getStream(), );
JsonObject item = doc["item"];
title = item["name"]; //This is a const char*
}
const char* title = nullptr;
void loop(void) {
getTitle();
u8g2.clearBuffer();
u8g2.setDrawColor(1);
u8g2.setFont(u8g2_font_6x12_tf);
u8g2.drawStr(1, 10, title);
u8g2.sendBuffer();
}
这样做可以吗?
当看到这样的事情时,你应该立即产生怀疑。
这是因为在getTitle
中,您正在向本地object ( item
) 请求指针 - 但您稍后使用该指针,此时item
object 不再存在。
这意味着一旦你需要它,你的指针可能毫无意义——它可能不再引用你的数据,而是一些任意的其他字节(甚至导致崩溃)。
此问题与您使用的确切库无关,您通常可以通过在库文档中搜索“生命周期”或“对象所有权”来找到相关的、更具体的信息。
确保该item
(以及DynamicJsonDocument
,因为文档告诉您)在您使用数据时仍然存在。 例如:像这样:
void setTitle(const char *title)
{
u8g2.clearBuffer();
u8g2.setDrawColor(1);
u8g2.setFont(u8g2_font_6x12_tf);
u8g2.drawStr(1, 10, title);
u8g2.sendBuffer();
}
void updateTitle()
{
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, http.getStream(), );
JsonObject item = doc["item"];
setTitle(item["name"]);
}
另请参阅: https://arduinojson.org/v6/how-to/reuse-a-json-document/#the-best-way-to-use-arduinojson
您可以在需要解析数据时保持 JSON 文档“活动”:
/* "static" visibility, so that other c/cpp files ("translation units") can't
* mess mess with our JSON doc directly
*/
static DynamicJsonDocument doc(1024);
static const char *title;
void parseJson()
{
[...]
// super important to avoid leaking memory!!
doc.clear();
DeserializationError error = deserializeJson(doc, http.getStream(), );
// TODO: robustness/error handling (e.g. inbound JSON is missing "item")
title = doc["item"]["name"];
}
// may be nullptr when called before valid JSON was parsed
const char* getTitle()
{
return title;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.