【问题标题】:How one aligns structure fields in Squeak FFI如何在 Squeak FFI 中对齐结构字段
【发布时间】:2018-04-11 19:01:48
【问题描述】:

如果我定义这样的结构 struct foo {char x; float y ; char z; double t}; 对齐可以依赖于平台,但我希望在大多数架构/编译器上成员 x、y、z、t 的偏移量分别为 0、4、8、16。

如果我在 Squeak 中定义了相应的结构

ExternalStructure subclass: #Foo 
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'FFI-Tests'.

并用天真地定义字段

Foo class>fields
    ^#(
        (x 'char')
        (y 'float')
        (z 'char')
        (t 'double') )

然后使用Foo defineFields 生成访问器,我得到那些打包的偏移量:

Foo>>x
    ^handle unsignedCharAt: 1

Foo>>y
    ^handle floatAt: 2

Foo>>z
    ^handle unsignedCharAt: 6

Foo>>t
    ^handle doubleAt: 7

即分别为0,1,5,6的字段偏移量。

我应该如何获得与平台兼容的对齐方式?

  • 插入填充字段?
  • 强制以前的字段大小?
  • 忘记自动生成的东西,自己编写所有访问方法?

【问题讨论】:

    标签: smalltalk ffi squeak


    【解决方案1】:

    如果我强制将大小作为某些字段规范的第三个元素,那么我可以获得所需的偏移量。

    Foo class>>fields
        ^#(
            (x  'char'  4)
            (y  'float' )
            (z  'char'  8)
            (t  'double')
        )
    

    我更喜欢指定当前字段的对齐方式而不是强制前一个字段的大小,但是,也许有人会找到更好的解决方案。

    请注意,它是以字节为单位的大小。如果我用 short 替换 char,那么如果我想获得相同的偏移量 0、4、8、16,我必须在第 3 列中保持相同的字节大小规范。

    Foo class>>fields
        ^#(
            (x  'short'  4)
            (y  'float' )
            (z  'short'  8)
            (t  'double')
        )
    

    【讨论】:

    • 通常有一条规则规定,例如,在您的示例中,长度为 4 的字段(如 y 'float')必须对齐到 4,等等。因此可能会有一些自动对齐,或者至少一些尝试。
    • 如果对齐可能是特定于平台的,但仍然特定于 Squeak FFI 的外部类型(即原子类型或结构类型),那么将这些信息存储在 ExternalType 中以在映像启动时更新是有意义的如果检测到平台更改。场对齐计算的范围和背景是什么?我宁愿不用写在#fields...
    • 同时,Squeak FFI 中已对 OS/arch 特定对齐进行了编程。在撰写本文时,此答案确实记录了现有解决方案,但一旦解决了 API,该问题将值得更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多