Этот вопрос напоминает
сериализовать любой тип данных как вектор <uint8_t> - использовать reinterpret_cast?
template <typename T>
inline void pack (std::vector< uint8_t >& dst, T& data) {
uint8_t * src = static_cast < uint8_t* >(static_cast < void * >(&data));
dst.insert (dst.end (), src, src + sizeof (T));
}
распаковать
template <typename T>
inline void unpack (vector <uint8_t >& src, int index, T& data) {
copy (&src[index], &src[index + sizeof (T)], &data);
}
Я пытаюсь упаковать любые типы данных в массив байтов.
q1: У меня есть утомительная реализация с использованием uint8_t *, я надеюсь, что выбор вектора является лучшим.
q2: Я не могу правильно упаковать std :: string с указанной выше функцией. Пожалуйста, дайте мне знать, насколько удобна вышеуказанная функция при упаковке всех типов данных
Пожалуйста, дайте мне знать, как включить std :: string в вышеупомянутый soluntion, т.е. pack и std :: string в вектор
Типы данных, которые я хочу упаковать:
все PODs std :: строковый вектор сам..
Внешняя проблема:
Я хочу упаковать класс, подобный этому, в массив байтов
class StartPeerSessionRequest : public Request {
public:
StartPeerSessionRequest();
virtual ~StartPeerSessionRequest();
void composeRequestwithHardCodeValues();
vector<uint8_t> packRequestWithTemplate();
private:
uint16_t mProtocolVersion;
uint16_t mSessionFlags;
uint16_t mMaxResponseLength;
string mMake;
string mModel;
string mSerialNumber;
uint8_t mTrackDelay;
string mHeadUnitModel;
string mCarModelYear;
string mVin;
uint16_t mVehicleMileage;
uint8_t mShoutFormat;
uint8_t mNotificationInterval;
};
class Message {
public:
Message();
virtual ~Message();
void composeMessage(vector<uint8_t> data, uint16_t opcode, uint16_t lengthOfData);
uint16_t packetheader;
uint16_t length;
uint16_t request_response_id;
uint16_t opcode;
uint16_t checksum;
vector<uint8_t> data;
}
Byte Array Тип данных, который я выбрал, является вектором (uint8_t)
Я хочу записать его в файл устройства или отправить через сеть bluetooth. Я не хочу десериализовать тот же класс, что и он. Я получаю ответ, который снова является байтовым массивом, и мне нужно в конечном итоге распаковать ответ другому классу
tl; dr: Используйте библиотеку сериализации, такую как Boost.Serialization или Protocol Buffers.
Ad 1) Вектор в порядке. Изменение: но поток будет лучше.
Ad 2) Ну, вы не можете сериализовать объекты с косвенным образом таким образом, потому что вы получите только указатель на фактические данные, а не на сами данные. И вы можете сериализовать простые старые данные (стандартная компоновка в C++ 11); или, скорее, не гарантируется десериализационный объект, который не является обычным старым/стандартным макетом, приведет к созданию рабочего объекта. std::string
(или любой другой контейнер) не является POD и содержит косвенность (std::string
- это особый вид вектора).
Там нет никакого способа для сериализации/пакета произвольных объектов нестандартного-макета в массив байт без специальной поддержки. Либо вы должны писать функции сериализации и десериализации для каждого такого типа, либо вам нужно отказаться от требования к байтовому массиву и использовать что-то вроде boost :: any для сохранения информации о типе и правильного вызова конструкторов и деструкторов для вас за кулисами. Обратите внимание, что boost::any
сам является объектом нестандартного макета с косвенностью.
Редактирование объявлений:
Я не хочу десериализовать тот же класс, что и он.
Да, да. На другом конце соединения. Таким образом, либо
Существуют тысячи способов сериализации каждого типа. Строка может быть сериализована как длина, а контент или контент, завершаемый указанным терминатором (обычно 0 байт), целое число (и размер строки - целое число) можно сериализовать в различное фиксированное количество байтов в разных порядках (в конце), использовать переменную кодирование длины и т.д.
И затем происходят изменения. Я вижу, что вы включили версию протокола. Но вам также нужно написать код десериализации, чтобы делать разные вещи на основе версии, что в общем случае означает, что это делается по-члену в любом случае (вы хотите вывести ту же структуру, независимую от версии, чтобы поддерживать нормальный код) и т.д.
Если у вас нет определенного протокола, я рекомендую вам посмотреть библиотеки Boost.Serialization и Protocol Buffers.
Если по какой-то причине вы не можете их использовать (если только цель не ограничена, вы должны иметь возможность: я работаю над мобильным приложением, которое использует как Boost, так и Protobuf и работает на всех современных мобильных платформах), по крайней мере, прочитайте их технические описания и, возможно, посмотрите в коде, чтобы вы знали, как сделать сериализацию хорошо.