2012-01-30 3 views
0

수신 데이터, 바이트 순서 및 정렬을 '직렬화'reinterpret_cast 우리는 POD는 구조체 말을 가지고 있고, 나는이 할 경우 최종

char* ptr = reinterpret_cast<char*>(A); 
char buf[20]; 
for (int i =0;i<20; ++i) 
    buf[i] = ptr[i]; 
network_send(buf,..); 

잡 원격 상자를 종료하는 경우, 반드시 동일한 하드웨어되지 않습니다 또는 OS, 나는 안전하게 '때 unserialize'에이 작업을 수행 할 수 있습니다

void onRecieve(..char* buf,..) { 
    A* result = reinterpret_cast<A*>(buf); // given same bytes in same order from the sending end 

는 '결과는'항상 유효 할 것인가? C++ 표준은 POD 구조로 상태를 바꿉니다. reinterpret_cast의 결과는 첫 번째 멤버를 가리켜 야하지만, 수신 끝이 다른 플랫폼이라 할지라도 실제 바이트 순서가 정확함을 의미합니까?

+1

에 대한 컴파일러 핸들을 templatefor이 사용하고시키는 고려할 수 있습니다. 한 플랫폼이 빅 엔디안이고 다른 플랫폼이 리틀 엔디안 인 경우를 고려하십시오. [네트워크 바이트 순서] (http://en.wikipedia.org/wiki/Endianness#Endianness_in_networking)이 매우 문제가 발생했습니다 ... – Cameron

+0

패딩은 플랫폼에 따라 다를 수도 있습니다 – bdonlan

답변

1

아니요, 불가능합니다. 당신은 지금까지 결코 다시 객체 포인터, char*에 "아래로"캐스트 할 수 있습니다 : 코드에서

Source     Destination 
    \      /
     \      /
     V      V 
read as char* ---> write as if to char* 

:

Foo Source; 
Foo Destination; 

char buf[sizeof(Foo)]; 

// Serialize: 
char const * ps = reinterpret_cast<char const *>(&Source); 
std::copy(ps, ps + sizeof(Foo), buf); 

// Deserialize: 
char * pd = reinterpret_cast<char *>(&Destination); 
std::copy(buf, buf + sizeof(Foo), pd); 

한마디로 : 객체를 원하는 경우가 있습니다 에는 개체가 있습니다. 실제로 무작위 인 경우 (예 : 원하는 유형의 실제 객체 주소가 아닌 경우) 임의의 메모리 위치를 으로 가장 할 수 없습니다.입니다.

+0

좋아, 내가 미끼를 데려 갈거야 ... * 왜 우리는 임의의 메모리 위치가 객체라고 가정 할 수 없는가? (플랫폼이 동일하고 소스 바이트가 같은 유형의 유효한 (POD) 객체로부터 온다고 가정 할 때)? 귀하의 방법에 +1. 그것은 정렬 문제도 처리해야합니다. – Cameron

+0

@Cameron, OP는 플랫폼이 _ 반드시 동일하지 않으면 안전할지 묻고 있습니다. – bdonlan

+0

@bdonlan : 그렇습니다.하지만 Kerrek는 (심지어는하지 말아야 할) 동일한 플랫폼. – Cameron

0

당신은 아니, 항상 유효하지 않습니다 당신

template<typename T> 
struct base_type { 
    union { 
     T scalar; 
     char bytes[sizeof(T)]; 
    }; 
    void serialize(T val, byte* dest) { 
     scalar = val; 
     if is_big_endian { /* swap bytes and write */ } 
     else { /* just write */ } 
    } 
};