[英]Buffer gets overwritten
我在ESP8266(類似Arduino的板上)上遇到了這個問題,但是這個問題是關於c / c ++的,所以我在這里問這個問題。
我對c / c ++之類的本地語言沒有太多經驗,我面臨一個奇怪的問題,這使我發瘋。 所以我使用的是Wemos D1 mini(ESP8266),它使用一個類調用ConfigManager
從eeprom中讀取配置文件。 配置文件的格式為json,所以我使用ArduinoJson解析內容。 我已經在標頭中聲明了StaticJsonBuffer
和指向JsonObject
指針,如代碼示例所示:
//FILE: ConfigManager.h
#ifndef ConfigManager_H
#define ConfigManager_H
#include <Arduino.h>
#include <ArduinoJson.h>
#include <FS.h>
#include "Logger.h"
class ConfigManager {
public:
Settings *settings;
ConfigManager();
void read_from_eeprom();
private:
File configFile;
JsonObject *json;
StaticJsonBuffer<200> jsonBuffer;
void open_file(const char *permission);
void read_json();
void recreate_file();
void create_json();
void check_success();
void populate_settings();
void clean_up();
};
#endif
調用read_from_eeprom
函數時,它將打開文件並調用read_json
函數:
void ConfigManager::read_json() {
size_t size = configFile.size();
Log.verbose("[ConfigManager] Config file size: %d", size);
std::unique_ptr<char[]> buf(new char[size]);
configFile.readBytes(buf.get(), size);
Log.verbose("[ConfigManager] File content: %s", buf.get());
Log.verbose("[ConfigManager] Parsing json");
json = &jsonBuffer.parseObject(buf.get());
Log.notice("[ConfigManager] Json is:");
json->printTo(Serial);
Serial.println();
}
接下來是對check_success()
的調用
void ConfigManager::check_success() {
Log.notice("[ConfigManager] Json is:");
json->printTo(Serial);
Serial.println();
bool should_recreate = true;
if (json->success()) {
Log.notice("[ConfigManager] Parsed json successfully");
auto version = json->get<const char*>("version");
if (version) {
if (strcmp(version, Settings::current_version) == 0) {
Log.notice("[ConfigManager] Config version is up2date");
should_recreate = false;
} else {
Log.warning("[ConfigManager] Config version outdated");
}
} else {
Log.warning("[ConfigManager] Invalid config file");
}
} else {
Log.warning("[ConfigManager] Config file is not valid json");
}
if (should_recreate) {
Log.notice("[ConfigManager] Recreating config file");
recreate_file();
create_json();
}
Log.notice("JSON IS: ");
json->prettyPrintTo(Serial);
Log.notice("[ConfigManager] Sucessfully read json");
}
所以我注意到文件內容很好。 例如{"version":"0.2","led_count":"64"}
。
然后解析json,該json將成功並記錄json對象,該對象又是{"version":"0.2","led_count":"64"}
。
之后函數返回,並調用check_success
,這再次將json對象的內容打印到日志中,但是這一次似乎已經覆蓋了JsonBuffer,這導致json對象被破壞。 這次,記錄的內容為{"v␂":"0.2","led_count":"64"}
(一些奇怪的獨角獸字符隨着源代碼的改變而改變)。 我試圖弄清楚現在已經發生了很多小時,但是我被困住了。 有人可以指出正確的方向來解決這個問題嗎? 謝謝!
完整的日志可以在此處找到,以及ConfigManager.h
和ConfigManager.cpp
*我更願意在評論中寫下來,因為我沒有arduino,也無法驗證我的建議100%有用。 但是我不能使用帶有“我的聲譽”的評論:)。 因此,如果我的回答沒有幫助,請不要按“減號按鈕”。
據這似乎期間需要使用JSON緩沖區保持原有JSON字符串。
- 將JSON字符串在內存中保留足夠長的時間
該庫從不進行內存復制。 這對字符串值有重要意義,這意味着庫將返回指向字符串塊的指針。
例如,假設您像這樣解析[“ hello”,“ world”]:
char [] json =“ [\\” hello \\“,\\” world \\“]”;
StaticJsonBuffer <32>緩沖區;
JsonArray&array = buffer.parseArray(json);
const char * first = array [0];
const char * second = array [1];
在這種情況下,第一個和第二個都是指向原始字符串json內容的指針。 因此,這僅在json仍在內存中時才起作用。
因此,嘗試使std :: unique_ptr buf成為類成員(與StaticJsonBuffer相同)並檢查其工作方式是有道理的。
順便說一句,IMO std :: vector在那里會更適合...而且我不確定unique_ptr是否會正確刪除數組。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.