Необъяснимое поведение массива символов после использования `deserializeJson`

array json

Я использую библиотеку 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"}

Есть ли для этого какая - то причина ? это ошибка ?

, 👍1

Обсуждение

Пожалуйста, смотрите: [Почему входные данные изменены?](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


2 ответа


Лучший ответ:

4

Когда вы передаете ввод char* в deserializeJson(), он изменяет ввод, чтобы избежать создания бесполезных копий.
Это режим "нулевого копирования" ArduinoJson.

В этом режиме анализатор JSON изменяет входные данные на месте. Выполняются следующие модификации:

  1. '\0' вставляются в конец каждой строки
  2. Экранированные специальные символы (например, \n) не экранируются

Пример:

char[] json = "{\"hello\":\"world\"}";
deserializeJson(doc, json);

После выполнения приведенной выше строки входная переменная, вероятно, содержит что-то вроде: "hello \ 0world \ 0".

Более подробную информацию вы можете найти в документации

,

Спасибо за ваш ответ - я не понимаю, почему _readmsg меняется (как концепция). Кто бы вы порекомендовали клонировать эту переменную, как я сделал, используя t2?, @Guy . D


0

Подводя итог ответу Бенуа Бланшона:

в исходном коде:

deserializeJson(DOC, _readmsg);

изменения в:

deserializeJson(DOC, (const char *)_readmsg); 
,