2009-10-11 2 views
0

struct.pack 같은 파이썬 있지만 C++에서 같은 고정 길이 문자열을 원하는. 내가 itoa (i,buffer,2) 생각했지만 문제는 길이가 플랫폼에 따라 달라질 수 있습니다. 플랫폼과 독립적으로 만들 수있는 방법이 있습니까?파이썬 struct.pack 해당 C++

답변

3

파이썬 구조체 패키지와 비슷한 완벽한 솔루션을 찾고 있다면 Google's Protocol Buffers Library을 확인해보십시오. 이를 사용하면 많은 문제 (예 : 엔디안 - 언어, 이식성, 버전 간 호환성)를 처리 할 수 ​​있습니다.

+0

+1 링크 –

1

typedef를 통해 정확한 너비 정수 유형을 정의해야합니다. 당신은 플랫폼 특정 방식으로 그렇게합니다. C99를 사용하는 경우 int16_t<stdint.h>에 미리 정의되어 있습니다. 그런 다음 해당 형식으로 캐스팅하고, 변수의 메모리 표현을 입력 할 수 있습니다 : 당신은 여전히 ​​엔디 언 다룰 필요가

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

공지 사항.

C99가없는 경우 컴파일 타임 또는 런타임 크기 테스트를 사용할 수 있습니다. 컴파일 타임 테스트에서는 다양한 기본 유형의 크기를 이미 계산 한 autoconf를 사용하여 컴파일 할 때 좋은 유형을 선택할 수 있습니다. 런타임에는 일련의 테스트가 있습니다. 테스트는 항상 동일한 결과가 나오기 때문에 런타임에는 다소 부적합합니다. autoconf의 대안으로 컴파일 타임 테스트를 위해 컴파일러/시스템 식별 매크로를 사용할 수도 있습니다.

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

을하고 ss.str().c_str()를 사용하려는 버퍼를 얻을 :

0

는 C++ 방법은 stringstream을 사용하는 것입니다.

+0

-1 고정 길이 문자열이 제공되지 않습니다. –

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에서 심각한 표정을 것입니다. 나는 내가 지금 가지고있는 바이너리 패킹 코드를 모두 작성할 때 존재했으면 좋겠다.