用标准便携式C 方法替换紧凑结构的“__attribute__ ((packed))”

如何解决用标准便携式C 方法替换紧凑结构的“__attribute__ ((packed))”

将几个值转换为用于无线电传输的字节串必须避免不需要的字节。在 ARM 目标(32 位)上使用 GCC 我使用“属性((打包))”。该指令是基于 GCC 的(正如我在此处读到的),因此通常不可移植 - 我更喜欢。示例:

typedef struct __attribute__ ((packed)) {
    uint8_t     u8;  // (*)
    int16_t     i16; // (*)
    float       v;
    ...
    uint16_t    cs;  // (*)
}valset_t;           // valset_t is more often used 
valset_t   vs;

(*) 值将使用 4 个字节而不使用 ((packed)) 属性,而不是根据需要使用一两个字节。用于传输的按字节访问:

union{
    valset_t    vs;                     // value-set
    uint8_t     b[sizeof(valset_t)];    // byte array
}vs_u;

使用 vs_u.b[i] .

  • 处理时间在这里并不重要,因为传输速度要慢得多。
  • 此处也不考虑 Endian,但在某些情况下可能会应用不同的 C 编译器。
  • 此任务的前辈帖子提供了一些见解,但也许同时在 C 中改进了打包和对齐功能?c)。

是否有更便携的 C 语言解决方案来执行此任务?

解决方法

包装/填充不是标准化的,因此严格来说结构/联合是不可移植的。 #pragma pack(1) 更常见一些,并且被许多不同的编译器(包括 gcc)支持,但它仍然不是完全可移植的。

另请注意,存在填充是有原因的,这些具有非标准包装的结构在某些系统上可能是危险的或不必要的低效。

用于存储协议等的唯一 100% 可移植数据类型是 unsigned char 数组。如果您为它们编写序列化器/反序列化器例程,您只能获得完全可移植的结构。这自然是以额外代码为代价的。反序列化示例:

valset_t data_to_valset (const unsigned char* data)
{
  valset_t result;
  result.something = ... ;
  ...
  return result;
}

如果存在某种网络字节序,您可以在同一例程中将网络字节序转换为 CPU 字节序。

请注意,您必须像上面的函数示例一样输入它。您不能编写如下代码:

unsigned char data[n] = ... ;
valset_t* vs = (valset_t*)data; // BAD

这在很多方面都很糟糕:对齐、填充、严格别名、字节序等等。

不过也可以反过来,使用 unsigned char* 逐字节检查或序列化结构体。但是,这样做仍然不能解决填充字节或字节序的问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?