Как преобразовать структуру переменного размера в массив символов - PullRequest
0 голосов
/ 29 августа 2018

Я пытаюсь сериализовать структуру для отправки в виде UDP-сообщения. У меня проблема в том, что структура содержит массив подструктур переменной длины, как показано ниже:

struct SubStruct
{
    short val1;
    short val2;
};

struct Message
{
    short numSubStructs;
    SubStruct* structs;
};

Метод, который я использую для отправки своих сообщений фиксированной длины, заключается в приведении структуры к unsigned char*. Ниже MSG_LENGTH равно sizeof(short) + numSubStructs * sizeof(SubStruct)

send(socket, reinterpret_cast<unsigned char*>(&someMessage), MSG_LENGTH);

Это прекрасно работает для всех моих сообщений фиксированной длины, но не для сообщений переменной длины. Глядя на данные, отправленные через сокет, я почти уверен, что он отправляет фактический адрес указателя структур.

У меня вопрос: есть ли способ сериализации такой структуры, кроме циклического перемещения по указателю (массиву) и добавления в некоторый буфер?

Спасибо

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Я не знаю элегантного способа сделать это в C ++. Однако есть несколько уродливых способов. По сути, выделите буфер достаточно большой, чтобы вместить всю «развернутую» структуру и подструктуру. Если последний член структуры является элементом переменного размера, то его не так уж и плохо поддерживать. Если есть несколько вложенных структур, это становится громоздким.

Вот пример стиля C.

struct example{
   int array_length;
   some_struct array[1];  // beware of padding in structure between the fields
}

int number_of_structs = 2;
example* ptr = malloc(sizeof(int)+ number_of_structs*sizeof(some_struct));
ptr->array_lenth = number_of_structs;
ptr->array[0].first_field = 1;
ptr->array[1].first_field = 2;

send(socket, ptr, sizeof(int)+ number_of_structs*sizeof(some_struct));

Есть также несколько (нестандартных) способов сделать это с массивами нулевой длины .

0 голосов
/ 29 августа 2018

Попробуйте что-то вроде этого:

char *serializedMessage = new char[sizeof(short) + someMessage.numSubStructs * sizeof(SubStruct)];
// Error check here

// Insert the count of structs
memcpy(serializedMessage, &someMessage.numSubStructs, sizeof(short));
// Copy the structs themselves.
memcpy(&serializedMessage[sizeof(short)], someMessage.structs,
        someMessage.numSubStructs * sizeof(SubStruct));

// Transmit serializedMessage

delete[] serializedMessage;

ПРИМЕЧАНИЕ При этом не учитывается порядок байтов данных, поэтому весьма вероятно, что он потерпит неудачу, если исходный и целевой компьютеры имеют разные порядки байтов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...