歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 帶指針的通信結構體32位與64位兼容

帶指針的通信結構體32位與64位兼容

日期:2017/3/1 10:06:40   编辑:Linux編程

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

場景分析:

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

  1. struct A
  2. {
  3. int count; //鏈表結點數
  4. int *b; //數據鏈表
  5. void* setPoint(void *p)//設置指針,傳入起始指針,返回結束指針
  6. {
  7. return (int*)p + count;
  8. }
  9. }
  10. struct B
  11. {
  12. int count; //鏈表結點數
  13. A *y; //A結構鏈表
  14. void* setPoint(void *p) //設置指針,傳入起始指針,返回結束指針
  15. {
  16. return (A*)p+count;
  17. }
  18. }

乍一看是不是很亂呢,確實,之所以在通信時使用這樣的結構,是為了傳送鏈表數據用的,也就是不固定的數據單元。

這裡就不深入討論這個結構的內存布局了,簡單說一下,內存布局分為頭部和尾部,頭部為結構體數據,尾部為結構體所包含的鏈表數據。

移植分析

主要討論移植的問題,眾所周知,指針在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位指針的簡單實現:

  1. class ptr
  2. {
  3. private:
  4. int shift;
  5. public:
  6. char* oprator=(char* p){ shift=(char*)this-p;return p;} //計算出p相對於this的偏移,保存下來,用作下次計算指針實際值用
  7. char* getptr(){return (char*)this + shift;}
  8. }
Copyright © Linux教程網 All Rights Reserved