Як прочитати значення ESP32 NVS у std::string

У нашому попередньому пості ми обговорили Як отримати довжину / розмір значення NVS на ESP32. На основі цього ми можемо прочитати значення NVS у std::string.

Стратегія

  1. Визначити розмір значення в NVS
  2. Виділити тимчасовий буфер визначеного розміру
  3. Прочитати значення з NVS у тимчасовий буфер
  4. Створити std::string зі значення
  5. Очистити тимчасовий буфер

Утилітна функція для читання значення NVS як std::string

У випадку, якщо ключ не існує в NVS, ця функція поверне порожній рядок ("").

read_nvs_to_stdstring.cpp
#include <nvs.h>
#include <string>

std::string ReadNVSValueAsStdString(nvs_handle_t nvs, const char* key) {
    /**
     * Стратегія:
     *  1. Визначити розмір значення в NVS
     *  2. Виділити тимчасовий буфер визначеного розміру
     *  3. Прочитати значення з NVS у тимчасовий буфер
     *  4. Створити std::string зі значення
     *  5. Очищення
     */
    // Крок 1: Отримати розмір ключа
    esp_err_t err;
    size_t value_size = 0;
    if((err = nvs_get_str(nvs, _key.c_str(), nullptr, &value_size)) != ESP_OK) {
        if(err == ESP_ERR_NVS_NOT_FOUND) {
            // Не знайдено, не помилка
            return "";
        } else {
            printf("Failed to get size of NVS key %s: %s\r\n", key, esp_err_to_name(err));
            return;
        }
    }
    // Крок 2: Виділити тимчасовий буфер для читання
    char* buf = (char*)malloc(value_size);
    // Крок 3: Прочитати значення у тимчасовий буфер.
    esp_err_t err;
    if((err = nvs_get_str(nvs, _key.c_str(), buf, &value_size)) != ESP_OK) {
        // "Не існує" вже оброблено раніше, тому це фактична помилка.
        // Ми припускаємо, що значення не змінилося між читанням розміру (крок 1) і зараз.
        // Якщо це припущення вірне, це завершиться з ESP_ERR_NVS_INVALID_LENGTH.
        // Однак це вкрай малоймовірно у всіх сценаріях використання.
        printf("Failed to read NVS key %s: %s\r\n", key, esp_err_to_name(err));
        free(buf);
        return "";
    }
    // Крок 4: Створити рядок
    std::string value = std::string(buf, value_size);
    // Крок 5: очищення
    free(buf);

    return value;
}

Приклад використання

Це передбачає, що ви налаштували myNvs, як ми показали у нашому попередньому пості Як ініціалізувати NVS на ESP32

example_usage.cpp
std::string value = ReadNVSValueAsStdString(myNvs, "MyKey");

Оптимізації C++17

Починаючи з C++17, ви, можливо, можете створити std::string напряму замість використання тимчасового буфера, оскільки є перевантаження .data(), що повертає не-const вказівник — тож ви можете писати напряму у буфер std::string.

Однак, оскільки моя PlatformIO-базована toolchain наразі не підтримує це, я ще не написав цей код.


Дивіться схожі статті за категоріями: C/C++, ESP8266/ESP32