Быстрая сериализация структур

Я пишу функцию для класса, который сериализует структуры, представляющие пакеты, в один буфер, который затем отправляется игрокам в многопользовательской игре. Чтобы сохранить эту функцию как можно более универсальной, я подумал, что было бы неплохо зарезервировать буфер для хранения структур и предоставить шаблонную функцию, которая построит структуру в буфере и вернет ссылку на нее. Вот что я пробовал ...

template <typename T>
T& writePacket()
{
    auto addr = m_writeOffset;
    *m_writeOffset = T();
    m_writeOffset += sizeof(T);
    return *addr;
}

Где m_writeOffset - указатель u8 * на следующий доступный байт.

Я уверен, что вернуть указатель на место в буфере, где находится структура, было бы намного проще, однако каждая из моих стоек пакетов содержит статический байт для заголовка, который позволяет клиентам идентифицировать типы пакетов. Вот несколько примеров пакетов, которые я могу отправить:

typedef u8 packet_header;

#pragma pack(push, 1)
struct CP_AttackEntity
{
    static const packet_header header = 0;
    u16 targetUID;
};
#pragma pack(pop)

#pragma pack(push, 1)
struct CP_EntityMoved
{
    static const packet_header header = 3;
    u16 uid;
    Vec2<u16> pos;
};
#pragma pack(pop)

u8, u16 - это просто typedef для uint8_t и т. д.

Я предполагаю, что причина, по которой это не работает, исходит из того, что я не совсем понимаю, как работают конструкторы. Когда пакет отправляется сервером или получен клиентом, пакеты полностью обнуляются. Может ли кто-нибудь указать мне правильное направление? Спасибо!

Обратите внимание, что статические члены не являются частью памяти объекта класса. Они существуют в собственном хранилище где-то в программе.

NathanOliver 09.08.2018 21:40

Можете ли вы дать минимальный воспроизводимый пример фактического кода, который вызывает все 0? *m_writeOffset = T(); выглядит как неопределенное поведение, и мне любопытно, как он вообще компилируется.

NathanOliver 09.08.2018 21:42

Так ли это? Я думал, что static означал бы, что переменная в каждом экземпляре структуры будет инициализирована определенным значением.

Liam Bury 09.08.2018 21:43

Неа. У статической переменной класса есть имя, которое передается классу (так что все объекты этого типа могут получить к нему доступ), но это единый объект, совместно используемый всеми экземплярами вне класса. Где-то у вас должен быть файл cpp, где у вас const packet_header CP_EntityMoved::header = 3;.

NathanOliver 09.08.2018 21:45

Вы хотите выполнить поиск в Google по запросу "новое место размещения". Вы можете начать здесь, как хороший пример.

Sam Varshavchik 09.08.2018 21:52

Вау! Это именно то, что я искал! Я изменю свой код, чтобы отразить обе ваши идеи, и расскажу, как это работает. Кроме того, я мог поделиться кодом сборки моей исходной функции с Натаном Оливером.

Liam Bury 09.08.2018 22:25

Также прочтите Обычные старые типы данных. Вы можете создать тривиальный конструктор, который инициализирует байт заголовка для вашего тега.

James Poag 09.08.2018 22:29
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
92
0

Другие вопросы по теме