我必须处理具有此类定义struct foo {float *data; size_t len;};
首先,我在Squeak
中定义相应的结构ExternalStructure subclass: #Foo
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'FFI-Tests'.
然后Squeak FFI可以处理不同的指针大小
我知道我必须通过Foo defineFields
重新生成字段访问权限。
但是,我可以在包装加载postscript中处理这个问题。
不幸的是,Squeak FFI没有size_t
支持。在我想支持的平台上,我知道它将是uint32_t和uint64_t,它们分别在Squeak FFI中转换为unsigned long
和unsigned long long
(这些类型是从Squeak图像大小查看的固定大小)。
那我该怎么办?有两个不同的Foo定义(但是我必须使用foo复制所有类型,并使用foo复制原型的接口)
Foo32 class>fields
^#(
(data 'float*')
(len 'ulong')
)
Foo64 class>fields
^#(
(data 'float*')
(len 'ulonglong')
)
还是有其他解决方案(例如手动定义字段/偏移/ byteSize和Smalltalk wordSize=4 ifTrue: [] ifFalse: []
)?
答案 0 :(得分:1)
我不能告诉你如何在Squeak中做到这一点,但我可以与你分享我们使用的Smalltalk方言所采用的方法。
#offsets64
类侧方法,可以使用64位#offsets64
字典将共享关联的值替换为64位偏移量。这不需要访问器上的条件逻辑,也不需要重新编译方法。如果字段的相对位置随平台变化,它也可以很好地工作。请注意,仅当结构布局取决于位长度时才需要执行步骤4和5(情况并非总是如此)。
如果您的系统支持“本地池字典”,这是一个具有类变量范围的池字典,则所有这些都可以简化。
答案 1 :(得分:1)
自mt.101起,您还可以为原子类型使用轻量级别名,这些原子类型通常以“类型常量”协议的形式在ExternalType class
上作为消息实现。参见source.squeak.org/FFI/FFI-Kernel-mt.101.diff
从<stddef.h>
和<stdint.h>
已知的typedef已有通用别名,例如size_t
(或uintptr_t
),您可以在字段定义中使用它们的外部结构和FFI调用的参数定义。
您现在可以跨平台编写您的示例:
Foo class>>fields
^ #(
(data 'float*')
(len 'size_t')
)
答案 2 :(得分:0)
现在我发现How one deals with typedefs in Squeak FFI报告的别名(typedef)我看到了一个解决方案:
定义Size_t别名
ExternalStructure subclass: #'Size_t'
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'FFI-Tests'
然后定义平台相关字段:
Size_t class>>fields
^(Smalltalk wordSize = 4)
ifTrue: [#( nil 'ulong' )]
ifFalse: [#( nil 'ulonglong' )]
然后执行Size_t defineFields
,现在我有一个Size_t类型,可以在函数原型中使用,也可以用于组合其他结构。 32位和64位图像的布局会有所不同,但我不必更改客户端代码。
对于特定于平台的&#uns; long&#39;而言,这有点问题。因为Windows 64位上的LLP64是受支持的平台之一:
ExternalStructure subclass: #'Unsigned_long'
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'FFI-Tests'
Unsigned_long class>>fields
^(Smalltalk wordSize = 4 or: [Smalltalk platformName = 'Win64'])
ifTrue: [#( nil 'ulong' )]
ifFalse: [#( nil 'ulonglong' )]
然后我必须在启动映像时检查平台的更改并重新编译所有ExternalType。
这个重新编译必须以正确的顺序执行,再一次,我在Squeak FFI中看不到任何支持,这将需要更多的工作......
编辑我修改了Squeak FFI,以便在另一个平台上恢复图像时引入自动重新编译支持,以及嵌套结构的正确初始化顺序。
见http://source.squeak.org/FFI/FFI-Kernel-nice.49.diff