最近做一個移植項目,將32位上的VPN移植到64位環境上。由於當初設計未考慮可移植性,導致移植時出現了很多的問題,其中最典型的一個問題就是通信結構帶指針的問題。
場景分析:
如下的兩個結構體,其中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位指針的簡單實現: