我想处理这样的结构struct foo {char *name; char **fields ; size_t nfields};
如果我在吱吱声中定义相应的结构
ExternalStructure subclass: #Foo
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'FFI-Tests'.
并天真地定义字段
Foo class>fields
^#(
(name 'char*')
(fields 'char**')
(nfields 'unsigned long')
)
然后用Foo defineFields
生成访问器,我得到了名称和字段的那些无差别类型:
Foo>>name
^ExternalData fromHandle: (handle pointerAt: 1) type: ExternalType char asPointerType
Foo>>fields
^ExternalData fromHandle: (handle pointerAt: 5) type: ExternalType char asPointerType
这很麻烦,字段访问器缺少第二个间接寻址。
我应该如何在规范中指定字段访问器?
如果不可能,如何手动定义它?
我对这个 HDF5 功能原型也有同样的问题:int H5Tget_array_dims(hid_t tid, hsize_t *dims[])
不接受以下语法:
H5Tget_array_dims: tid with: dims
<cdecl: long 'H5Tget_array_dims'(Hid_t Hsize_t * * )>
编译器在第二个*
之前argument expected ->
吠叫......
我补充说诉诸void *
,这完全绕过了类型检查 - 不太理想......
知道如何正确处理这样的原型吗?
自 Compiler-mt.435 以来,解析器不会再抱怨,而是回调ExternalType>>asPointerToPointerType
。查看 source.squeak.org/trunk/Compiler-mt.435.diff 和 source.squeak.org/FFI/FFI-Kernel-mt.96.diff
在撰写本文时,此类指针到指针类型将被视为常规指针类型。因此,您丢失了外部类型实际指向指针数组的信息。
什么时候需要这些信息?
- 在调用期间在 FFI 插件中强制参数时
- 在调用期间在 FFI 插件中构造返回的对象时
- 从结构字段和 FFI 调用返回值解释
ExternalData
实例时 - 在对象资源管理器等工具中
吱吱声中已经有几种RawBitsArray
。将String
和ExternalStructure
(包括打包或联合)添加到混合中,我们在 Squeak 中有各种对象来映射最里面的维度(即 int*、char*、void*)。ExternalData
可以表示多维数组的其他级别(即 int**、char**、void** 等)。
因此,这里还有剩余的任务:
- 将该指针尺寸信息存储在可以通过
ExternalType>>referencedType
找到的新外部类型中。我们可能想把新信息放到compiledSpec
.见 http://forum.world.st/FFI-Plugin-Question-about-multi-dimensional-arrays-e-g-char-int-void-td5118484.html - 更新
ExternalArray
中的值读取以解开一个指针的包装;并让结构字段访问器的代码生成器以类似的方式生成代码。 - 在插件中扩展参数强制以接受已经支持的数组的数组(即
String
等)