Cómo leer un valor NVS de ESP32 en std::string

En nuestra publicación anterior, discutimos Cómo obtener la longitud / tamaño del valor NVS en ESP32. Basado en eso, podemos leer un valor NVS en un std::string.

Estrategia

  1. Determinar el tamaño del valor en NVS
  2. Asignar un búfer temporal del tamaño determinado
  3. Leer el valor de NVS en el búfer temporal
  4. Crear std::string a partir del valor
  5. Limpiar el búfer temporal

Función utilitaria para leer el valor NVS como std::string

En caso de que la clave no exista en NVS, esta función devolverá una cadena vacía ("").

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

std::string ReadNVSValueAsStdString(nvs_handle_t nvs, const char* key) {
    /**
     * Estrategia:
     *  1. Determinar el tamaño del valor en NVS
     *  2. Asignar un búfer temporal del tamaño determinado
     *  3. Leer el valor de NVS en el búfer temporal
     *  4. Crear std::string a partir del valor
     *  5. Limpiar
     */
    // Paso 1: Obtener el tamaño de la clave
    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) {
            // No encontrado, sin error
            return "";
        } else {
            printf("Failed to get size of NVS key %s: %s\r\n", key, esp_err_to_name(err));
            return;
        }
    }
    // Paso 2: Asignar un búfer temporal para leer
    char* buf = (char*)malloc(value_size);
    // Paso 3: Leer el valor en el búfer temporal.
    esp_err_t err;
    if((err = nvs_get_str(nvs, _key.c_str(), buf, &value_size)) != ESP_OK) {
        // "Doesn't exist" ya ha sido manejado antes, así que esto es un error real.
        // Asumimos que el valor no cambia entre la lectura del tamaño (paso 1) y ahora.
        // En caso de que esa suposición sea válida, esto fallará con ESP_ERR_NVS_INVALID_LENGTH.
        // Sin embargo, esto es extremadamente improbable en todos los escenarios de uso.
        printf("Failed to read NVS key %s: %s\r\n", key, esp_err_to_name(err));
        free(buf);
        return "";
    }
    // Paso 4: Crear la cadena
    std::string value = std::string(buf, value_size);
    // Paso 5: limpiar
    free(buf);

    return value;
}

Ejemplo de uso

Esto asume que has configurado myNvs como hemos mostrado en nuestra publicación anterior Cómo inicializar NVS en ESP32

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

Optimizaciones de C++17

A partir de C++17, puedes posiblemente crear un std::string directamente en lugar de usar el búfer temporal, ya que hay una sobrecarga de .data() que devuelve un puntero no const - así que puedes escribir directamente al búfer del std::string.

Sin embargo, dado que mi toolchain basado en PlatformIO actualmente no soporta eso, no he escrito ese código todavía.


Echa un vistazo a artículos similares por categoría: C/C++ ESP8266/ESP32