2012-03-02 3 views
3

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

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

EDIT: потому что данные, которые я отправляю, просты, я решил просто использовать memcpy, указатели и функции hton*. Нужно ли мне манипулировать char каким-либо образом, чтобы отправить его по сети агностическим способом? (char используется только как байт, а не как символ).

+1

Не могли бы вы объяснить, что 'pack' /' unpack' делать на этих языках? – Mehrdad

+0

Пакет и распаковка используются для превращения переменных в двоичную строку и наоборот. Они очень полезны для создания пакетов и двоичных файлов и других бинарных взаимодействий. Языки, о которых я упоминал, имеют эту функцию в их стандартной библиотеке.C/C++ - нет. – Linuxios

+0

О хм ... FYI, это может быть даже невозможно. Это потребует большого количества метапрограммирования (или поддержки IDE), чтобы получить всю информацию о поле и такой ... единственный родной язык, который я знаю, который, вероятно, мог бы сделать это, - [D] (http://dlang.org/). – Mehrdad

ответ

1

Да: Используйте 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++, потому что язык уже позволяет получить доступ к двоичным его переменные представление как стандартная часть языка.

+2

Я знаю. Я хочу пакет/распаковать для портативного представления, а не локальное манипулирование байтами. – Linuxios

+1

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

+0

Это вообще не переносится. Вы не рассматриваете цели для начинающих, и, конечно, это работает только для типов POD (простые старые данные). – Correa

5

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

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

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

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

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

+0

Можете ли вы подробнее остановиться на '# прагма'? Я использую GCC. – Linuxios

+0

@ Linux_iOS.rb.cpp.c.lisp.m.sh : добавлены некоторые ссылки о '#pragma pack'. –

+0

hton */ntoh * конвертировать только между хостом по порядку (может быть большим или немного endian) и порядком сетевого байта (эффективно большой endian). Они не предоставляют способ сериализации/десериализуйте значения, которые хранятся в переносном стиле. Маленькие endian_. – fuzzyTew

 Смежные вопросы

  • Нет связанных вопросов^_^