带指针的通信结构体32位与64位兼容
来源:互联网 发布:办公软件有问题 编辑:程序博客网 时间:2024/05/21 17:02
最近做一个移植项目,将32位上的VPN移植到64位环境上。由于当初设计未考虑可移植性,导致移植时出现了很多的问题,其中最典型的一个问题就是通信结构带指针的问题。
场景分析:
如下的两个结构体,其中B在通信时做通信结构使用
- struct A
- {
- int count; //链表结点数
- int *b; //数据链表
- void* setPoint(void *p)//设置指针,传入起始指针,返回结束指针
- {
- return (int*)p + count;
- }
- }
- struct B
- {
- int count; //链表结点数
- A *y; //A结构链表
- void* setPoint(void *p) //设置指针,传入起始指针,返回结束指针
- {
- return (A*)p+count;
- }
- }
struct A{int count; //链表结点数int *b; //数据链表void* setPoint(void *p)//设置指针,传入起始指针,返回结束指针{return (int*)p + count;}}struct B{int count; //链表结点数A *y; //A结构链表void* setPoint(void *p) //设置指针,传入起始指针,返回结束指针{return (A*)p+count;}}
乍一看是不是很乱呢,确实,之所以在通信时使用这样的结构,是为了传送链表数据用的,也就是不固定的数据单元。
这里就不深入讨论这个结构的内存布局了,简单说一下,内存布局分为头部和尾部,头部为结构体数据,尾部为结构体所包含的链表数据。
移植分析
主要讨论移植的问题,众所周知,指针在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位指针的简单实现:
- class ptr
- {
- private:
- int shift;
- public:
- char* oprator=(char* p){ shift=(char*)this-p;return p;} //计算出p相对于this的偏移,保存下来,用作下次计算指针实际值用
- char* getptr(){return (char*)this + shift;}
- }
class ptr{private:int shift;public:char* oprator=(char* p){ shift=(char*)this-p;return p;} //计算出p相对于this的偏移,保存下来,用作下次计算指针实际值用char* getptr(){return (char*)this + shift;}}
- 带指针的通信结构体32位与64位兼容
- 带指针的通信结构体32位与64位兼容
- _SYSTEM_PROCESS 32位与64位的结构
- _SYSTEM_PROCESS 32位与64位的结构
- 学习windows驱动(32位与64位兼容)
- iOS开发之32位与64位,以及结构体对齐访问的问题
- 同时兼容32位与64位机器的php hash函数
- 同时兼容32位与64位机器的php hash函数
- ubuntu 12.04 64位设置兼容32位的实现
- UBUNTU 64位解决32位兼容的方法
- ubuntu 12.04 64位设置兼容32位的实现
- ubuntu 12.04 64位设置兼容32位的实现
- ubuntu 14.04 64位系统的解决32位兼容
- .so兼容32位和64位
- android 64位兼容32位
- 64位系统兼容32位工具
- 64位ubuntu 兼容32位
- 电脑的32位与64位
- jquery 循环显示div的示例代码
- 学习 C++的用途,(前辈总结)
- 深入浅出4G标准:LTE FDD和LTE TDD
- UIViewController的 dismissViewControllerAnimated:completion:方法
- 32位机指针为什么是4个字节 64位与32位机的区别
- 带指针的通信结构体32位与64位兼容
- 从32位程序开发进入64位程序开发
- WINDOWS_32位与64位系统的编程差异
- 64位与32位编程的数据类型区别
- android sqllite 支持的数据类型
- Java 集合(Collections)总结
- LeetCode(11) ContainerWithMostWater
- PHP运行出现Notice : Use of undefined constant 的解决办法
- CRM上线之路 走上了CRM实施顾问-第88天上班 -第19周