Хранение типа данных в C - PullRequest
0 голосов
/ 01 ноября 2011

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

У меня есть блок памяти длиной 10 байтов.(Мое приложение 64-битное с использованием Visual C.) То, что я хочу сделать, это поместить 1 unsigned int в байты 0-3, char в [4] и char в [5], а другой unsigned int в [6-9].

Я уже пробовал ssprintf.

Поэтому я пытаюсь найти способ 1) сохранить его в этом блоке памяти и 2) извлечь его.

Ответы [ 5 ]

3 голосов
/ 01 ноября 2011

IMO, хороший способ сделать это, определив структуру, содержащую данные, которые вы описали:

#pragma pack(1)
struct complex {
    uint32_t a; // 4 bytes
    char b[2]; // 2 bytes (without paddding)
    uint32_t c; // 4 bytes
};

Затем вы можете просто заполнить ваши данные:

struct complex var;
var.a = 10;
var.b[0] = 'x';
var.b[1] = 'y';
var.c = 20;

Примечаниедиректива #pragma pack(1) указывает компилятору использовать 1-байтовое выравнивание.Если вы не знаете, что это значит, вы можете прочитать о выравнивании структуры данных .

2 голосов
/ 01 ноября 2011

Вы обрабатываете байты (и вы не храните типы, вы просто храните в них данные).Вы можете либо объявить struct для заполнения ваших требований, либо скопировать байты данных (например, с memcpy) в соответствующие местоположения, например что-то вроде

unsigned int lastint;
char* buf;
memcpy (&lastint, buf+6, sizeof(lastint));

Однако имейте в виду, что при работе стакие низкоуровневые двоичные данные делают эти данные и ваше приложение чрезвычайно непереносимыми (и ломкими, так как они ломаются, когда приложение развивается).Существует больше «стандартных» двоичных форматов (например, XDR или ASN1).

2 голосов
/ 01 ноября 2011

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

// char *mem = <10_bytes>;

unsigned int x = 54;
unsigned int y = 10;

memmove(mem, &x, 4);
memset(mem + 4, 'A', 1);
memset(mem + 5, 'B', 1);
memmove(mem + 6, &y, 4);
1 голос
/ 01 ноября 2011

Вы можете использовать эту структуру:

#pragma pack(1)
struct TData {
    unsigned int a;
    char c1;
    char c2;
    unsigned int b; 
};

А потом по вашей функции:

int f()
{
    char buffer[10]; // your 10 
    struct TData *data = (struct TData*)buffer;
    printf("a: %d b: %b c1: %c c2: %c", data->a, data->b, data->c1, data->c2);
}
0 голосов
/ 01 ноября 2011
  1. Использовать "struct"

  2. (опционально) использовать директиву pack для конкретного компилятора, чтобы компилятор не дополнял поля.

  3. (опционально), используйте "memset" (или эквивалентный), чтобы обнулить блок

  4. Копировать данные поля за раз

PS: Microsoft MSVC и Gnu Gcc оба используют «#pragma pack (1)» для предотвращения заполнения.

...