2012-01-30 19 views
0

如果我們有一個POD結構說A,我這樣做:的reinterpret_cast爲「序列化」的數據,字節順序和對齊在接收端

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

如果recieving結束遙控盒,不一定是相同的硬件或操作系統,可我放心地這樣做是爲了「反序列化」:

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

沒有,也不會永遠是有效的。考慮一個平臺是大端的,另一個是小端的情況。 [網絡字節順序](http://en.wikipedia.org/wiki/Endianness#Endianness_in_networking)出現這個問題... – Cameron 2012-01-30 06:01:21

+0

填充也可以不同平臺 – bdonlan 2012-01-30 06:32:20

回答

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 2012-01-30 06:03:15

+0

@Cameron,OP詢問這是否安全,如果平臺不一定相同 – bdonlan 2012-01-30 06:22:15

+0

@bdonlan:好的,但是Kerrek似乎在說它不是(或者說不應該這樣做),即使在同一個平臺。 – Cameron 2012-01-30 06:39:19

0

您可以考慮使用templatefor這一點,並讓編譯器爲您處理

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 */ } 
    } 
}; 
相關問題