LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1272|回复: 11

如何使代码自适应little/big endian?

[复制链接]
发表于 2005-7-4 10:47:43 | 显示全部楼层 |阅读模式
代码需要在little和big上跑,如何让代码自适应呢?
发表于 2005-7-4 22:06:07 | 显示全部楼层
在两种环境有交互的时候用上hton和ntoh系列函数
内部应该没关系吧
回复 支持 反对

使用道具 举报

发表于 2005-7-4 22:19:06 | 显示全部楼层
要是整个代码都需要从little-end型移植到big-end(或者相反的话)一定要重新编译吧!
毕竟体系结构都不一样了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-7-4 22:25:28 | 显示全部楼层
有没有#ifdef之类的方法呢?

就像#ifdef __LINUX可以区分windows和linux一样
回复 支持 反对

使用道具 举报

发表于 2005-7-4 22:48:29 | 显示全部楼层
你测试一下这个宏__i386  还有 i386
回复 支持 反对

使用道具 举报

发表于 2005-7-5 08:33:59 | 显示全部楼层
(1)写代码时避免 endia 相关的操作
比如下列代码与 endia 相关(假设为 little):
u_char ch[2];
u_short i;
ch[0] = *(u_char *)&i;
ch[1] = *((u_char *)&i + 1);

改成
ch[0] = i & 0x00FF;
ch[1] = i >> 8;

(2)如果(1)无法实现,可以在程序启动时判断 endia,置全局变量,需要的时候根据该变量选择不同的操作。判断 endia 的代码论坛里有,可以搜到。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-7-5 09:10:26 | 显示全部楼层
在某规范中,规定一个分组格式的第16和第17个字节表示一个长度

代码中,用unsigned char *data来接收此分组。


  1. typedef union{
  2. short num;
  3. unsigned char a[2];
  4. } aaa;

  5. aaa number;

  6. number->a[0] = data[15];
  7. number->a[1] = data[16];
复制代码


后边引用number->num

这个应该是little endian吧

如何把上边的代码自适应呢?
回复 支持 反对

使用道具 举报

发表于 2005-7-5 09:44:44 | 显示全部楼层
处理的前提是知道 unsigned char *data 表示的长度 是big endian还是little endian
一般网络上传的都是 big endian, x86系列芯片都是 little endian

假设 data 是big endian

  1. unsigned short number;
  2. number = data[15];
  3. number = number << 8;
  4. number += data[16];
复制代码


或者


  1. unsigned short number;
  2. number=ntohs( *((unsigned short*)&(data[15])) );
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-7-5 10:50:46 | 显示全部楼层
在我的代码(7楼)中,data是作为recvfrom的buffer参数的,有一个变量int datalen说明data的字节数

我代码的后两句赋值,应该是little endian吧,用在x86上

如果我希望这两个赋值语句也可以“同时”用于比如m68k上,改如何修改呢?
回复 支持 反对

使用道具 举报

发表于 2005-7-5 16:05:20 | 显示全部楼层
data 是little endian,  也就是高8位在后, 应该这样写

  1. unsigned short number;
  2. number = data[16];
  3. number = number << 8;
  4. number += data[15];
复制代码


这样不用修改代码,只需要重新编译,在x86和m68k上都可以用。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表