Smalltalk 如何在Squeak FFI中对齐结构字段

Smalltalk 如何在Squeak FFI中对齐结构字段,smalltalk,ffi,squeak,Smalltalk,Ffi,Squeak,如果我定义这样的结构structfoo{charx;float y;char z;double t}对齐可能依赖于平台,但我希望在大多数体系结构/编译器上,成员x、y、z、t的偏移量分别为0,4,8,16 如果我在Squeak中定义相应的结构 ExternalStructure subclass: #Foo instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category

如果我定义这样的结构
structfoo{charx;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

我应该如何获得与平台兼容的校准

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

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

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
中,以便在检测到平台更改时在映像启动时更新。场对齐计算的范围和上下文是什么?我不想把它写在
#字段中
…同时,操作系统/arch特定的对齐已经在Squeak FFI中编程。在撰写本文时,这个答案确实记录了现有的解决方案,但一旦API得到解决,这个问题就应该得到更新的答案。