Необъяснимое поведение массива символов после использования `deserializeJson`
Я использую библиотеку RF24 для отправки сообщений между 2 микроконтроллерами: 1) ESP8266 (без Wi-Fi, тот же код может быть скомпилирован на любую плату Arduino) 2) pro-Micro.
Сообщение отправляется в формате JSON с использованием библиотеки ArduinoJson для
сериализации
и десериализации
сообщений.
Хотя весь код работает так, как ожидалось, я получаю сообщение об ошибке в функции "RFread", из-за которой массив _readmsg теряет свое содержимое после использования
deserializeJson
.
Ниже прилагается соответствующая часть функции "RFread". Пояснения в приведенном ниже коде. Пожалуйста, обратите внимание на "Mark [X]" в коде и последовательном выводе:
char _readmsg[32]; <---- Storing input in this array
char t2[32]; <---- variable to clone value
radio.read(&_readmsg, sizeof(_readmsg)); <---- getting RF input and store it in `_readmsg`
strcpy(t2, _readmsg); <---- cloning, part of error seeking
Serial.print("first: "); <---- printing initial value stored. OK. marked [A] in Serial output
Serial.println(_readmsg);
Serial.print("duplicate: "); <---- printing clone. OK. marked [B] in Serial output
Serial.println(t2);
if (key != nullptr) <--- check if "msg" key was sent in message
{
StaticJsonDocument<80> DOC;
deserializeJson(DOC, _readmsg); <---- **error beyond this point**
Serial.print("second: ");
Serial.println(_readmsg); <---- printing wrong value. marked [C] in Serial output
if (DOC.containsKey(key))
{
const char *outmsg = DOC[key];
if (out != nullptr)
{
strcpy(out, outmsg);
return true;
}
}
else
{
Serial.print("third: ");
Serial.println(_readmsg); <---- still error. marked [D] in Serial output
Serial.print("duplicate2: ");
Serial.println(t2); <---- clone variable is OK. marked [E] in Serial output
strcpy(out, t2); // if key not present, return entire message
return 0;
}
и в последовательном порту:
message sent OK <---- irrelevant for debug
15:18:14.934 -> first: {"id":"Port","msg":"fff"} <----[A]
15:18:14.934 -> duplicate: {"id":"Port","msg":"fff"} <----[B]
15:18:14.934 -> second: id <----[C]
15:18:14.934 -> third: id <----[D]
15:18:14.934 -> duplicate2: {"id":"Port","msg":"fff"} <----[E]
15:18:14.934 -> Error. no such key. got reply: {"id":"Port","msg":"fff"}
Есть ли для этого какая - то причина ? это ошибка ?
@Guy . D, 👍1
Обсуждение2 ответа
Лучший ответ:
Когда вы передаете ввод char* в deserializeJson(), он изменяет ввод, чтобы избежать создания бесполезных копий.
Это режим "нулевого копирования" ArduinoJson.
В этом режиме анализатор JSON изменяет входные данные на месте. Выполняются следующие модификации:
'\0'
вставляются в конец каждой строки- Экранированные специальные символы (например
, \n
) не экранируются
Пример:
char[] json = "{\"hello\":\"world\"}";
deserializeJson(doc, json);
После выполнения приведенной выше строки входная переменная, вероятно, содержит что-то вроде: "hello \ 0world \ 0"
.
Более подробную информацию вы можете найти в документации
Спасибо за ваш ответ - я не понимаю, почему _readmsg
меняется (как концепция). Кто бы вы порекомендовали клонировать эту переменную, как я сделал, используя t2
?, @Guy . D
Подводя итог ответу Бенуа Бланшона:
в исходном коде:
deserializeJson(DOC, _readmsg);
изменения в:
deserializeJson(DOC, (const char *)_readmsg);
- ArduinoJSON: использование ссылки на ссылку при анализе массива массивов
- Возможно ли иметь массив массивов int?
- Ошибка: invalid application of 'sizeof' to incomplete type 'int []' при попытке вычислить размер массива в библиотеке
- Инициализация массива структур
- Невозможно создать массив типа const char*
- Работает ли конструкция int array[100] = {0} на Arduino?
- NodeMCU (Arduino IDE) «DynamicJsonBuffer» не был объявлен в этой области
- Массив динамического размера в качестве члена класса
Пожалуйста, смотрите: [Почему входные данные изменены?](https://arduinojson.org/v6/faq/why-is-the-input-modified /), @Benoit Blanchon
Кроме того, пожалуйста, проверьте код ошибки, возвращаемый [deserializeJson()](https://arduinojson.org/v6/api/json/deserializejson /), @Benoit Blanchon
Ошибка @BenoitBlanchon выдает "OK", @Guy . D