帶指標的通訊結構體32位與64位相容

2021-06-19 14:49:44 字數 1602 閱讀 2669

最近做乙個移植專案,將32位上的vpn移植到64位環境上。由於當初設計未考慮可移植性,導致移植時出現了很多的問題,其中最典型的乙個問題就是通訊結構帶指標的問題。

場景分析:

如下的兩個結構體,其中b在通訊時做通訊結構使用

[cpp]view plain

copy

print?

struct a  

}  struct b  

}  

struct a

}struct b

}

乍一看是不是很亂呢,確實,之所以在通訊時使用這樣的結構,是為了傳送鍊錶資料用的,也就是不固定的資料單元。

這裡就不深入討論這個結構的記憶體布局了,簡單說一下,記憶體布局分為頭部和尾部,頭部為結構體資料,尾部為結構體所包含的鍊錶資料。

移植分析

主要討論移植的問題,眾所周知,指標在32位下的長度為32位,而在64 位下的長度為64位,那麼我們問題出現了。

我們知道,通訊協議一定需要保證通訊雙方的資料報一模一樣的,現在上面的這種情況如果32位與64位機通過b結構通訊時,必然導致協議不一致而

解析錯誤的問題。原因很簡單,就是指標長度變了。

那麼怎麼解決這個問題了,首先想的當然是在64位機上採用一套跟32位機一模一樣的結構體。

方法一、

在64位機上,多定義一套結構體(32位相容結構),用int代替指標,請注意,由於指標在傳到對端時必然失效,所以,這裡的指標在通訊過程中已經沒有作用了。

用int做佔位,處理時採用 標準結構體處理,在傳送的時候將其轉換成32位相容結構,再傳送出去,這樣,對方在收到時就會協議相容。

但問題是,這樣做就會多做一次結構體解碼和編碼,即對整個多維鍊錶的賦值,這是乙個工作量很大的過程,特別當這樣的結構多次出現時。

方法二、

自己實現乙個指標類,用來替代結構體中出現的指標,該類模擬指標,但長度只有32位。

問題立刻出現了,怎麼才能夠用32位的長度模擬64位的指標呢,答案是不可能。

正常情況下確實是不可能的,應為無論如何,32位都沒辦法表示64位的長度。

但在這種通訊結構中卻是有可能的,因為通訊結構大小一定小於2^32。

而通訊結構中的指標指向的是通訊結構中的某乙個區域。

於是,可以採用偏移的方式模擬64位指標。

這樣就很順其自然地解決了所有的問題,只需要簡單地對指標進行替換,就可以實現32與64位通訊相容

下面給出64位下模擬32位指標的簡單實現:

[cpp]view plain

copy

print?

class ptr  

//計算出p相對於this的偏移,儲存下來,用作下次計算指標實際值用

char* getptr()  

}  

class ptr

//計算出p相對於this的偏移,儲存下來,用作下次計算指標實際值用

char* getptr()

}

32位系統與64位系統的區別

64位作業系統只能安裝在64位電腦上 cpu必須是64位的 同時需要安裝64位常用軟體以發揮64位 x64 的最佳效能。32位作業系統則可以安裝在32位 32位cpu 或64位 64位cpu 電腦上。當然,32位作業系統安裝在64位電腦上,其硬體恰似 大馬拉小車 64位效能就會大打折扣。第三,運算速...

結構體指標與結構體中變數的指標

結構體指標與結構體變數指標的區別,在進行實現的工程專案中會有許多地方用到結構體指標的情況,在使用這前都需要先malloc一塊空間之後才能有空間進入儲存資料,例項 如下 include includetypedef struct student student t,pstudent t void pr...

64位與32位作業系統的不同

乙個電腦處理資料是有規定的格式的。32位的電腦存放資料的形式是對每個資料用32個二進位制位元組來存放。64位的意思就是用64位個二進位制位元組來存放。64位作業系統的資料寬度為64位,64位指令集可以執行64位資料指令,也就是說處理器一次可提取64位資料 只要兩個指令,一次提取8個位元組的資料 比3...