Как разыменовать несколько пустых указателей в структурах в 1 фрагмент памяти? - PullRequest
0 голосов
/ 07 февраля 2011

Я работаю над проектом, в котором мне нужно отправить через определенный стек IPC (в моем случае LCM), и мне нужно предоставить IPC структуру переменной длины. У меня

struct pack1 {int value1; int value2;};
struct pack2 {void *data; int data_size;}; 
//data won't always point to pack1 types

У меня есть указатель на pack2, и мне нужно что-то вроде сериализации, чтобы я мог отправить это pack2 по сети другому процессу.

Кто-нибудь знает как?

Ответы [ 4 ]

2 голосов
/ 07 февраля 2011

LCM поддерживает массивы переменной длины, см. Раздел «Массивы» в справочном руководстве: http://lcm.googlecode.com/svn-history/r401/www/reference/lcm/tutorial-lcm-language.html

Однако ваши данные доступны через void*, который является просто указателем на «неизвестный» тип. Если ваши данные всего лишь байты, то они могут работать с байтовым массивом, как показано в определении LCM:

struct pack2 {
  int32_t data_size;
  unsigned char data[data_size};
}
1 голос
/ 07 февраля 2011

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

# Each row is a 32-bit unsigned value in network byte order.
| number of pairs following     |
| [0].value1                    |
| [0].value2                    |
| [1].value1                    |
| [2].value2                    |
  ...
| [N].value1                    |
| [N].value2                    |

Хорошие примеры - как делать такие вещи, так и как их документировать - можно найти в RFC TCP и IP или в спецификации PNG.*

0 голосов
/ 08 февраля 2011

Помните, что структура может содержать любое количество байтов заполнения.Это особенно хлопотно при написании протокола данных любой формы.При использовании sizeof () вы должны быть уверены, что у компилятора отключено заполнение.Переносимый способ состоит в том, чтобы пройти через член структуры по элементу и отправить их.

0 голосов
/ 07 февраля 2011

Вы можете сделать это так:

struct pack2        *p;

p = (struct pack2 *) malloc( sizeof(struct pack2) + 1024 );
p->data_size = 1024;
p->data = (char *) p + sizeof(struct pack2);

Единственное предостережение: вы должны убедиться, что целевая платформа поддерживает порядковый номер исходной платформы в data_size, и вы должны быть уверены, что struct pack2 имеет одинаковый размер на обеих платформах.

...