【问题标题】:Absolute addressing fields in a record type [duplicate]记录类型中的绝对寻址字段[重复]
【发布时间】:2015-06-03 19:43:06
【问题描述】:

我正在尝试与嵌入式系统交互,该系统以相当简单的格式传输和接收数据,但对大小有严格的要求。

在 C 中,您可以使用联合类型来公开一些变量数据,这些变量数据可能具有不同类型,位于内存中的同一位置。将此联合类型的变量添加到结构中,然后您可以(小心地)以各种名称和类型引用该结构字段:

为简单起见,请忽略字节对齐和打包

typedef enum { F1_V1, F1_V2, F1_V3 } FLAG_1_T;
typedef enum { F2_V1, F2_V1        } FLAG_2_T;

typedef union
{
  FLAG_1_T flag_1;
  FLAG_2_T flag_2;
}
FLAG_T;

typedef struct
{
  BYTE_T  id;
  INT32_T value;
  FLAG_T  flag;
}
DATA_ITEM_T;

所以现在我可以将flag 字段解释为FLAG_1_TFLAG_2_T

我想在 Delphi 2010 中使用同样的方法。我尝试通过对记录字段使用绝对寻址来实现这一点:

type
  FLAG_1_T = ( F1_V1, F1_V2, F1_V3 );
  FLAG_2_T = ( F1_V1, F1_V2        );

type
  DATA_ITEM_T = record
    id     : BYTE_T;
    value  : INT32_T;
    flag_1 : FLAG_1_T;
    flag_2 : FLAG_2_T absolute flag_1;
  end;

但是编译失败,语法错误E2029 ';' expected but identifier 'absolute' found

如果我将这些标志声明带到记录类型定义之外(但与记录类型定义在同一范围内),它编译得很好:

请注意,这对我要完成的工作毫无用处

type
  FLAG_1_T = ( F1_V1, F1_V2, F1_V3 );
  FLAG_2_T = ( F1_V1, F1_V2        );

type
  DATA_ITEM_T = record
    id     : BYTE_T;
    value  : INT32_T;
  end;

var
  flag_1 : FLAG_1_T;
  flag_2 : FLAG_2_T absolute flag_1;

那么为什么我不能在记录中这样做呢?有没有其他方法可以做到这一点?

【问题讨论】:

    标签: delphi record discriminated-union


    【解决方案1】:

    您可以使用带有variant part 的记录类型将 C 联合转换为 Delphi:

    type
      FLAG_T = record
        case Boolean of
          False: (flag_1: FLAG_1_T);
          True: (flag_2: FLAG_2_T);
      end;
    

    【讨论】:

    • 记录中的布尔值是否不需要任何额外的空间?我的意思是,FLAG_T 的大小会与FLAG_1_TFLAG_2_T 中最大的一个精确相同吗?
    • 只有当您使用字段标签声明它时才会保留额外的空间,例如case B: Boolean of... 这在链接文档中也有解释:“标签,如果有的话,功能作为一个额外的字段..." 如果没有标签,是的,FLAG_T 的大小将与 FLAG_1_TFLAG_2_T 的最大大小完全相同。
    • @ardnew 它确实解决了您的问题。您创建一个单独的类型来表示联合并将其包含在您的外部记录中。
    • type TMyRec = record i: Integer; union: record case Integer of 0: (d: Double); 1: (s: Single); end; b: Boolean; end; 但你需要原谅格式,因为这在 cmets 中是一团糟!!!将其粘贴到 Delphi 中,然后按 CTRL+D!
    • FWIW 我为我转换为变体记录的每个联合中的案例定义了新的枚举类型。那样看起来更清楚
    猜你喜欢
    • 1970-01-01
    • 2016-09-24
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2019-09-22
    相关资源
    最近更新 更多