简体   繁体   English

在 ESP32 上处理 const char*

[英]Handling of const char* on ESP32

I'm working on making some Spotify API calls on an ESP32.我正在对 ESP32 进行一些 Spotify API 调用。 I'm fairly new to C++ and while I seem to got it working how I wanted it to, I would like to know if it is the right way/best practice or if I was just lucky.我对 C++ 还很陌生,虽然我似乎让它按照我想要的方式工作,但我想知道这是否是正确的方法/最佳实践,或者我是否只是幸运。 The whole thing with chars and pointers is still quite confusing for me, no matter how much I read into it.不管我读了多少,关于字符和指针的整个事情对我来说仍然很困惑。

I'm calling the Spotify API, get a json response and parse that with the ArduinoJson library.我正在调用 Spotify API,获得 json 响应并使用 ArduinoJson 库对其进行解析。 The library returns all keys and values as const char* The library I use to display it on a screen takes const char* as well.该库将所有键和值作为const char*返回。我用来在屏幕上显示它的库也采用const char* I got it working before with converting it to String, returning the String with the getTitle() function and converting it back to display it on screen.我在将它转换为字符串之前让它工作,使用 getTitle() function 返回字符串并将其转换回屏幕上显示。 After I read that Strings are inefficient and best to avoid, I try to cut out the converting steps.在我读到字符串效率低下且最好避免之后,我尝试减少转换步骤。

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();
}

Is it okay to do it like that?这样做可以吗?

This is not fine.这不好。

When seeing something like this, you should immediately become suspicious.当看到这样的事情时,你应该立即产生怀疑。

This is because in getTitle , you are asking a local object ( item ) for a pointer-- but you use the pointer later, when the item object no longer exists .这是因为在getTitle中,您正在向本地object ( item ) 请求指针 - 但您稍后使用该指针,此时item object 不再存在

That means your pointer might be meaningless once you need it-- it might no longer reference your data, but some arbitrary other bytes instead (or even lead to crashes).这意味着一旦你需要它,你的指针可能毫无意义——它可能不再引用你的数据,而是一些任意的其他字节(甚至导致崩溃)。

This problem is independent of what exact library you use, and you can often find relevant, more specific information by searching your library documentation for "lifetime" or "object ownership".此问题与您使用的确切库无关,您通常可以通过在库文档中搜索“生命周期”或“对象所有权”来找到相关的、更具体的信息。

FIX使固定

Make sure that item (and also DynamicJsonDocument , because the documentation tells you so,) both still exist when you use the data.确保该item (以及DynamicJsonDocument ,因为文档告诉您)在您使用数据时仍然存在。 eg: like this:例如:像这样:

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"]);
}

See also: https://arduinojson.org/v6/how-to/reuse-a-json-document/#the-best-way-to-use-arduinojson另请参阅: https://arduinojson.org/v6/how-to/reuse-a-json-document/#the-best-way-to-use-arduinojson

Edit: If you want to keep parsing/display update decoupled编辑:如果你想保持解析/显示更新解耦

You could keep the JSON document "alive" for when the parsed data is needed:您可以在需要解析数据时保持 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.

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