__attribute __ ((упакованный)) альтернатива

рассмотрим следующую структуру:

typedef struct __attribute__((packed)) a{
int a1;
int b2;
char cArray[5];
int c3;
} Mystruct;

Теперь в моем коде я делаю это:

char source[50];
Mystruct mm;
//...
//initialization and other codes
//...
memcpy(&mm,source,sizeof(mm));

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

Итак, мой вопрос: есть ли другой способ достичь того, чего я хочу?
Можно ли сделать то же самое (заполнение из строки) переменными-членами класса в c ++? Если да, то как?

3

Решение

Я настоятельно рекомендую вам купить и прочитать Написать портативный код. Вы не хотите использовать этот подход. Не только потому, что он не переносимый (думаю, проблемы с бесконечностью), но он влияет на производительность и атомарность (32-разрядный доступ без выравнивания не является атомарным на x86 без префикса LOCK). Гораздо лучше маршал / распаковать, Хотя это немного больше работы заранее.

Идея маршалинга / демаршалинга заключается в преобразовании ваших данных из одного формата в другой и обратно. Это то, что нравится фреймворкам Google Protocol Buffers, ZeroMQ, и многие другие делают передачу данных портативным способом. В основном у вас есть специализированные функции, которые берут ваши «строковые» данные, о которых вы говорили, и вы анализируете их, утверждать это, а затем назначить его в вашей структуре. Вы увидите, что маршалинг и сериализация взаимозаменяемо используются во многих контекстах.

Например, в вашем случае у вас может быть функция с прототипом:

int
unmarshal_mystruct(const char *data, MyStruct &m);

Внутренне, вы бы проанализировали данные из dataи заселить m, Это становится утомительным, поэтому так много людей используют фреймворки.

5

Другие решения

Используйте код сериализации / десериализации. То есть например, прочитать в байтовом массиве, а затем преобразовать значения в структуру. Это то, что делают многие фреймворки (т. Е. CORBA и т. Д.).

Недостатки: больше кода для записи.

Преимущества: лучшая мобильность, совместимость между платформами LE / BE. Например, ваш код может не работать на некоторых устройствах ARM.

Пример (структура):

typedef struct a
{
int a1;
int b2;
char cArray[5];
int c3;
} Mystruct;

Пишу:

void write_int(FILE *f, int value)
{
int32_t tmp = htonl(value); // write in BE form
fwrite(&tmp, 4, 1, f);
}

void a_write(Mystruct *d, FILE *f)
{
write_int(f, d->a1);
write_int(f, d->b2);
fwrite(d->cArray, 5, 1, f);
write_int(f, d->c3);
}

Чтение:

void read_int(FILE *f, int *value)
{
int32_t tmp;
fread(&tmp, 4, 1, f);
*value = ntohl(tmp);
}

void a_read(Mystruct *d, FILE *f)
{
read_int(f, &d->a1);
read_int(f, &d->b2);
fread(d->cArray, 5, 1, f);
read_int(f, &d->c3);
}
3

По вопросам рекламы [email protected]