jenya7 0 17 января, 2017 Опубликовано 17 января, 2017 · Жалоба Мне нужно логировать данные. Вот пишу универсальный логер. Натраиваю куда писать (SD, Flash, UART) и какие данные писать. Я планирую передавать указатель на переменную или структуру которые надо логировать. Но как быть дальше? Данные надо сериализовать (упаковать в массив) для передачи дальше. И тут я застрял. void LOG_Send(uint32_t storage, void *data, uint32_t size) { char buf[size]; //size of data??? uint32_t i = 0; while (data) { buf[i++] = (char *)(*data++); } switch (storage) { case SD: SD_Log("log.txt", buf); break; case FLASH: Flash_Log(log_addr, buf); break; case UART: UART_SendString(UART2, buf); break; } } В строке buf[i++] = (char *)(*data++); ругается на приведение типов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
novikovfb 17 17 января, 2017 Опубликовано 17 января, 2017 · Жалоба В строке buf[i++] = (char *)(*data++); ругается на приведение типов. data имеет тип void*, его инкрементировать нельзя (размер указываемой области не определен). Самое простое - скопировать data в обычный указатель на char и не мучиться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 17 января, 2017 Опубликовано 17 января, 2017 · Жалоба data имеет тип void*, его инкрементировать нельзя (размер указываемой области не определен). Самое простое - скопировать data в обычный указатель на char и не мучиться. понял. сделал так. char buf[size]; //size of data??? char *data_p = data; uint32_t i = 0; while (data) { buf[i++] = (*data_p++); } кстати а если я логирую во флеш и хочу потом вытащить данные - их надо десириализовать? то есть надо где то хранить информацию о днных которые я логировал? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 17 января, 2017 Опубликовано 17 января, 2017 · Жалоба то есть надо где то хранить информацию о днных которые я логировал? Да, конечно. В противном случае вы будете иметь сырые данные, которые только на глаз и можно будет разглядеть :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 17 января, 2017 Опубликовано 17 января, 2017 · Жалоба Да, конечно. В противном случае вы будете иметь сырые данные, которые только на глаз и можно будет разглядеть :rolleyes: понял. спасибо. не все так просто. придется поломать голову. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 1 17 января, 2017 Опубликовано 17 января, 2017 · Жалоба Лучше сериализовать данные, а не передавать их в бинарной форме. Как вариант — JSON использовать или просто строки "параметр = значение". Иначе смена даже разрядности процессора может привести к куче геморроя. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 17 января, 2017 Опубликовано 17 января, 2017 (изменено) · Жалоба Лучше сериализовать данные, а не передавать их в бинарной форме. Как вариант — JSON использовать или просто строки "параметр = значение". Иначе смена даже разрядности процессора может привести к куче геморроя. если это SD то да , есть такая возможность. но если это Flash - нужно писать побайтово. я хочу сделать что то универсальное. Изменено 17 января, 2017 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 1 17 января, 2017 Опубликовано 17 января, 2017 · Жалоба Тогда в самом начале сохраняйте информацию о типе данных (фиксированном, т.е. не int, а, скажем, int32_t), конечности (big/little/mid), выравнивании (скажем, на 32-битной системе int16_t скорее всего будут с выравниванием по 4 лежать) и количестве данных. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 17 января, 2017 Опубликовано 17 января, 2017 (изменено) · Жалоба В строке buf[i++] = (char *)(*data++); ругается на приведение типов. Вы приводите к указателю содержимое data, а не data. Нужно так: buf[i++] = *((char*)data)++; Изменено 17 января, 2017 пользователем aiwa Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 1 17 января, 2017 Опубликовано 17 января, 2017 · Жалоба Еще проще и быстрее по производительности было бы вызвать memcpy. Хотя, если содержимое data не меняется, то зачем вообще его куда-то копировать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 17 января, 2017 Опубликовано 17 января, 2017 · Жалоба Еще проще и быстрее по производительности было бы вызвать memcpy. Хотя, если содержимое data не меняется, то зачем вообще его куда-то копировать? Или data передавать в функции в качестве аргумента. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 17 января, 2017 Опубликовано 17 января, 2017 · Жалоба Иначе смена даже разрядности процессора может привести к куче геморроя. Да быть этого не может. Если вы их правильно положите, и правильно извлечёте. TCP/IP пакет - это бинарные данные, а гоняются между всеми возможными платформами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 17 января, 2017 Опубликовано 17 января, 2017 (изменено) · Жалоба Еще проще и быстрее по производительности было бы вызвать memcpy. Хотя, если содержимое data не меняется, то зачем вообще его куда-то копировать? я заранее не знаю тип данных. это может быть int, float или struct. пользователь конфигурирует что и куда логировать. вобще это в основном показания датчиков или системные ошибки. кстати да. memcpy (buf, data, sizeof (data)) вполне работает Изменено 17 января, 2017 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 1 17 января, 2017 Опубликовано 17 января, 2017 · Жалоба TCP/IP пакет - это бинарные данные, а гоняются между всеми возможными платформами. И постоянно вызываются функции вроде htoa и т.п. Но TCP/IP — понятно, там потоки большие. А вот если данных немного, лучше не заморачиваться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 17 января, 2017 Опубликовано 17 января, 2017 · Жалоба Следующий шаг: template<typename T> void LOG_Send(uint32_t storage, T const & data) { LOG_Send(storage, &data, sizeof(T)); } Позволяет писать в каждой точке вызова LOG_send(storage, my_struct) вместо LOG_send(storage, &my_struct, sizeof(my_struct)) и связанных с этим ошибок. Но противники плюсов будут привычно ныть об "увеличении объема кода и подъедании ограниченных ресурсов". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться