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得到解决,这个问题就应该得到更新的答案。