упаковать / распаковать функции для C ++ - PullRequest
3 голосов
/ 02 марта 2012

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

Мне нужна библиотека C или C ++, которая реализует функции Python / Ruby / Perl, такие как pack / unpack. Существует ли такая библиотека?

РЕДАКТИРОВАТЬ: Поскольку данные, которые я отправляю, просты, я решил просто использовать memcpy, указатели и функции hton*. Нужно ли каким-либо образом манипулировать char для отправки его по сети независимо от платформы? (char используется только как байт, а не как символ).

Ответы [ 3 ]

5 голосов
/ 02 марта 2012

В C / C ++ обычно вы просто пишете struct с различными членами в правильном порядке (для правильной упаковки могут потребоваться специфичные для компилятора прагмы) и выгружаете / считываете его в / из файла с необработанным fwrite / fread (или read / write при работе с потоками C ++). На самом деле pack и unpack были рождены, чтобы читать вещи, сгенерированные этим методом.

Если вам вместо этого нужен результат в буфере, а не в файле, это еще проще, просто скопируйте структуру в буфер с помощью memcpy.

Если представление должно быть переносимым, ваши основные проблемы - это порядок байтов и упаковка полей; Первая проблема может быть решена с помощью различных функций hton*, а вторая - с директивами, специфичными для компилятора.

В частности, многие компиляторы поддерживают директиву #pragma pack (см. здесь для VC ++, здесь для gcc), которая позволяет вам управлять (нежелательным) заполнением, которое компилятор можно вставить в struct, чтобы его поля были выровнены по удобным границам.

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

5 голосов
/ 02 марта 2012
1 голос
/ 02 марта 2012

Да: используйте std::copy из <algorithm> для работы с байтовым представлением переменной.Каждая переменная T x; может быть доступна как байтовый массив через char * p = reinterpret_cast<char*>(&x)p может рассматриваться как указатель на первый элемент массива char[sizeof(T)].Например:

char buf[100];
double q = get_value();

char const * const p = reinterpret_cast<char const *>(&q);
std::copy(p, p + sizeof(double), buf);

// more stuff like that

some_stream.write(buf) //... etc.

И чтобы вернуться назад:

double r;

std::copy(data, data + sizeof(double), reinterpret_cast<char *>(&r));

Короче говоря, вам не нужен выделенный pack / unpack в C ++, потому что язык ужепозволяет получить доступ к двоичному представлению его переменных как стандартной части языка.

...