IPAddress print problem
- Войдите на сайт для отправки комментариев
Втр, 26/02/2019 - 16:13
Наткнулся на странное поведение компилятора (?)... Объяснить ничем пока не могу, прошу глянуть - может глаз замылился:
#include <IPAddress.h>
typedef struct {
IPAddress ipAddr;
uint32_t justNumber;
} config_t;
config_t systemConfig;
////////////////////////////////////////////////////////////////////////
void setup() {
uint8_t structSize = sizeof(config_t);
Serial.begin(115200);
Serial.print("Start of test\nsizeof(config_t): ");
Serial.println(structSize);
// 3 => OK
// 1 + 2 => OK
// 1 + 4 => OK
// 1 + 3 => FAIL
// (1)
memset(&systemConfig, 42, structSize);
// (2)
//Serial.print("IP: "); Serial.println(((config_t) systemConfig).ipAddr);
// (3)
Serial.print("IP: "); Serial.println(systemConfig.ipAddr);
// (4)
//Serial.print("justNumber: "); Serial.println(systemConfig.justNumber);
Serial.println("End of test");
}
void loop() {}
Проблема наблюдается, как только делаю memset структуре, членом которой является IPAddress (с простыми типами данных похоже всё ОК) - при выводе в Serial происходит визуальное подвисание (выводится часть текста), на большом прожекте МК уходит в ребут. Вобщем, всё указывает на запись в память по адресу "куда попало".
Если не делать memset, либо явно указывать Stream-у тип структуры - всё проходит чисто.
Сталкивался ли кто-нибудь с подобными спецэффектами?
Ттип IPAddress какой?
Да там целый класс под капотом, как я понимаю: "C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\IPAddress.h" (большая копипаста выйдет).
Причем, этот лжывый Си++ срабатывает нормально, если объявить структурную переменную локально, а не глобально. И почти нормально, если заволатилить глобальную.
Ну вы даете :) IPAddress это кто ? :) Почему он 6 байт, хотя для хранения ip адреса нужно 4... Что в этих ДВУХ байтах ? Можно ли их затирать чем попало ?
Дет, че у меня с сайтом седня... ? Пишет мне красным, что не может какую то почту отправить, задваивает сообщения, виснет. Рекомендует обратиться к админам ! Если ты редактируешь мои сообщения, значит ты админ, а раз ты админ, обращаюсь к тебе !
Ну вот я уже и тово - читаю в .h, что это класс. Но тогда мне что-то непонятно, почему всё ОК, если структурная переменная объявлена локально и как приведение типа исправляет "затёртое".
На самом деле я в структуру читал блок из EEPROM и наступил на граблю в тот момент, когда решил попечатать в консоль, чего там в структуру попало. И тут у меня началось... Потом уже обнаружил, что memset точно так же срабатывает, посему его в пример бахнул. Зря, может...
Компилятор знает, что такое ipAddr, он знает это с момента объявления. Процедура которая выводит на печать IP адрес не включена в структуру, а находится отдельно, там куда ее полажил компилятор. Когда ты желаешь напечатать этот адрес у тебя никаких конфликтов не возникает, потому что эти два "лишних" байта в танцах не учавствуют.А вот когда тебе понадобится какая либо операция которая эти два байта юзает - получаем крашинг.
Дет, че у меня с сайтом седня... ? Пишет мне красным, что не может какую то почту отправить, задваивает сообщения, виснет. Рекомендует обратиться к админам ! Если ты редактируешь мои сообщения, значит ты админ, а раз ты админ, обращаюсь к тебе !
Я могу только лишние сообщения скрывать. У самого такая же байда с утра, сапщения двояца/трояца. Не знаю что с сайтом, надо челом бить Алехандеру.
Я могу только лишние сообщения скрывать. У самого такая же байда с утра, сапщения двояца/трояца. Не знаю что с сайтом, надо челом бить Алехандеру.
У него с SMTP проблема. Когда пост сабмитится, форумный движок начинает отсылать e-mail, но соединиться в SMTP сервером не может и висит, пока таймаут не выйдет. Человек же видит, что ничего не происходит и нервно тапает на "Сохранить" ещё пару раз. Вот отсюда и дубли. Я, например, не тыркаю, а спокойно жду таймаута, вследствии чего генерирую только одно сообщение в форум.
Ну вот я уже и тово - читаю в .h, что это класс. Но тогда мне что-то непонятно, почему всё ОК, если структурная переменная объявлена локально и как приведение типа исправляет "затёртое".
может класс никак не может выбрать между IPv4 и IPv6?
IPAddress и IP6Address это разные классы. Кстати по стандартам устройство может иметь и тот и другой адрес, одновременно.
IPAddress и IP6Address это разные классы.
Открываю IPAddress.h и вижу там одновременно код и для v4 и для v6
Ну вот я уже и тово - читаю в .h, что это класс. Но тогда мне что-то непонятно, почему всё ОК, если структурная переменная объявлена локально и как приведение типа исправляет "затёртое".
может класс никак не может выбрать между IPv4 и IPv6?
Он же не девка красная в магазине хранцузского платья...
Нет, я с бруклей вполне согласен, что тут произошло головное запутывание, так как я всегда оперировал IPAddress-ом как uint8_t[4], но лжывый Си++ под прилавком мухлевал, совал это в класс, а когда надо было - отдавал, как массив.
Сейчас же я решил воспользоваться удобством Wiring-а и бахнул класс в структуру, а её уже скормил EEPROM.put(). Записаться-то оно записалось, а вот при считывании через EEPROM.get() уже вышло кое-что нежданное.
Сейчас выкинул нах... из структуры IPAddress, поставил uint8_t[4] и делаю Serial.println(IPAddress(systemConfig.ipAddr)). Не так красиво, конечно, но всё работает, не ребутится.
Придется к DetSemen-у итить на поклон - пусть классам подучит ))
Это к Пуху. У него и автоматы смазанные есть. Я в Сишных классах где-то около нуля так и болтаюсь до сих пор. ¦(
А я стараюсь ipv4 хранить в uint32_t, для удобства юзаю такую штуку ntohl() :) Очень удобно с масками и диапазонами оперировать, проверять вхождение в диапазон и прочее.
У меня со словом "класс" ассоциируется другое слово - "адрес". А забивать адреса при помощи memset, либо даже читать туда из EEPROM - занятие весьма многообещающее.)))