python struct.pack在c ++中的等价物

时间:2009-10-11 13:43:03

标签: c++ struct.pack

我想要一个固定长度的字符串来自一个数字,就像python中存在的struct.pack但是在c ++中。我想到itoa (i,buffer,2)但问题可能是它的长度将取决于平台。有没有办法让它独立于平台?

4 个答案:

答案 0 :(得分:3)

如果您正在寻找类似于Python的struct包的完整解决方案,您可以查看Google's Protocol Buffers Library。使用它可以解决很多问题(例如字节序,语言可移植性,跨版本兼容性)。

答案 1 :(得分:1)

您需要通过typedef定义精确宽度的整数类型;你以特定于平台的方式做到这一点。如果您使用C99,int16_t中预定义了<stdint.h>。然后,您可以转换为该类型,并键入变量的内存表示形式:

int16_t val = (int16_t) orig_val;
void *buf = &val;

请注意,您仍然需要处理字节序。

如果您没有C99,则可以使用编译时或运行时大小测试。对于编译时测试,请考虑使用autoconf,它已经计算了各种基本类型的大小,以便您可以在编译时选择一个好的类型。在运行时,只需要进行一系列sizeof测试。请注意,这对于运行时来说有点不合适,因为测试总是会得到相同的结果。作为autoconf的替代方法,您还可以使用编译器/系统标识宏进行编译时测试。

答案 2 :(得分:1)

这是一个开始:

typedef std::vector<uint8_t> byte_buffer;

template <std::size_t N>
void append_fixed_width(byte_buffer& buf, uintmax_t val) {
    int shift = ((N - 1) * 8);
    while (shift >= 0) {
        uintmax_t mask = (0xff << shift);
        buf.push_back(uint8_t((val & mask) >> shift));
        shift -= 8;
    }
}

template <typename IntType>
void append_bytes(byte_buffer& buf, IntType val) {
    append_fixed_width<sizeof(IntType)>(buf, uintmax_t(val));
}

int main() { // usage example
     byte_buffer bytes;
     append_bytes(bytes, 1);   // appends sizeof(int) bytes
     append_bytes(bytes, 1ul); // appends sizeof(unsigned long) bytes
     append_bytes(bytes, 'a'); // appends sizeof(int) bytes :p
     append_bytes(bytes, char('a')); // appends 1 byte
     return 0;
}

Append_bytes会将任何整数类型附加到使用std::vector<uint8_t>表示的字节缓冲区中。值以big endian字节顺序打包。如果您需要更改此设置,请调整append_fixed_width以不同的顺序遍历该值。

这些函数构建一个原始字节缓冲区,因此无论解码器是什么,它都有责任了解其中的内容。 IIRC,这也是struct.pack的作用;换句话说,struct.unpack的调用者需要提供相同的格式字符串。您可以编写append_fixed_width的变体来代替TLV

template <typename TagType, typename ValueType>
void append_tlv(byte_buffer& buf, TagType t, ValueType val) {
    append_fixed_width<sizeof(TagType)>(buf, uintmax_t(t));
    append_fixed_width<sizeof(std::size_t)>(buf, uintmax_t(sizeof(ValueType)));
    append_fixed_width<sizeof(ValueType)>(buf, uintmax_t(val));
}

我会认真看看Jeremy's suggestion。我希望它在我编写现在所有的二进制打包代码时已存在。

答案 3 :(得分:0)

C ++的方式是使用stringstream

stringstream ss;
int number=/*your number here*/;
ss<<number;

并获取您使用ss.str().c_str()的缓冲区。