【问题标题】:How to guarantee bits of char and short for communication to external device如何保证与外部设备通信的 char 位和 short 位
【发布时间】:2010-12-19 09:46:23
【问题描述】:

您好,我正在编写一个库,用于通过 rs-232 串行连接与外部设备进行通信。

通常我必须传达一个包含 8 位 = 1 字节字符或 16 位 = 2 字节数字的命令。如何以便携的方式执行此操作?

主要问题

从阅读其他问题看来,标准不保证 1byte = 8bits, (在标准 $1.7/1 中定义)

C 中的基本存储单元 ++内存模型是字节。一个字节至少大到足以包含 基本执行的任何成员 字符集,由一个 连续的位序列, 其中的数量是 实现定义

如何保证char的位数?我的设备需要准确的 8 位,而不是至少 8 位。

我意识到几乎所有实现都有 1byte = 8 位,但我很好奇如何保证它。

Short->2 字节检查

希望您不介意,我还想运行我为您提出的短 -> 2 字节转换的解决方案。我是字节转换和跨平台可移植性的新手。

为了保证short的字节数我猜我需要需要

  1. 做一个 sizeof(short)。如果 sizeof(short)=2 转换为字节并检查字节顺序(如here

  2. 如果 sizeof(short)>2 然后将 short 转换为字节,检查字节顺序(如here),然后检查最重要的字节是否为空并删除它们?

    这是正确的做法吗?有没有更好的办法?

非常感谢

【问题讨论】:

    标签: c++ cross-platform serial-port


    【解决方案1】:

    AFAIK,与串行端口的通信在某种程度上取决于平台/操作系统,所以当你编写它的低级部分时,你会非常了解平台、它的字节序和 CHAR_BIT。这样问题就没有任何意义了。

    另外,不要忘记 UART 硬件能够传输 7 或 8 位字,因此它不依赖于系统架构。

    编辑: 我提到 UART 的字是固定的(让我们考虑 8 位的模式 3,作为最标准的),硬件本身不会发送超过 8 位,所以通过给它是一个send 命令,它将准确发送 8 位,而不管机器的 CHAR_BIT 是什么。这样,通过对byte

    使用一个单独的send
    unsigned short i;
    send(i); 
    send(i>>8);
    

    您可以确定它会做正确的事情。
    此外,一个好主意是看看 boost.asio 到底在做什么。

    【讨论】:

    • 是的,我认为你的权利。我正在使用 boost.asio 库进行低级通信,所以我没有想到。 char = 16 位系统上的用户无法使用该库是真的吗?如果我要求它发送字母“a”,这将是我的设备预期位数的两倍?
    • 谢谢,不过我还是有点困惑(抱歉)。所以从 char=16 位实现: char c = 'a';发送(c);会发送一半的字符?是否可以将 16 位字符转换为 8 位以发送我的设备期望的位?
    • @Tom: a 是 ASCII 字符 0x61,它总是适合 8 位。如果 CHAR_BIT 大于 8,则高位为零。
    【解决方案2】:

    This thread 似乎建议您可以使用来自<climits>CHAR_BITThis page 甚至建议 8 是 char 中的最小位数......不知道标准中的引用与此有何关系。

    对于固定大小的整数类型,如果使用 MSVC2010 或 GCC,您可以依赖 C99 的 <stdint.h>(即使在 C++ 中)来定义 (u)int8_t(u)int16_t,它们分别保证为 8 位和 16 位宽.

    【讨论】:

      【解决方案3】:

      CHAR_BIT 来自 <climits> 标头告诉您字符中的位数。这是至少 8。此外,short int 使用至少 16 位来表示其值。这是由最小值范围保证的:

      type             can at least represent
      ---------------------------------------
      unsigned char             0...255
      signed char            -127...127
      unsigned short            0...65535
      signed short         -32767...32767
      unsigned int              0...65535
      signed int           -32767...32767
      

      here

      关于可移植性,每当我编写依赖于 CHAR_BIT==8 的代码时,我都会这样写:

      #include <climits>
      
      #if CHAR_BIT != 8
      #error "I expect CHAR_BIT==8"
      #endif
      

      正如您所说,几乎所有平台都是如此,如果不是在特定情况下,它将无法编译。这对我来说已经足够便携了。 :-)

      【讨论】:

      • 是的,我喜欢你对尺码的检查。我会用这个,谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 2012-02-14
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 2011-07-15
      • 1970-01-01
      相关资源
      最近更新 更多