如何处理Squeak FFI中的多指针级别(如char **)

时间:2018-04-11 20:50:51

标签: smalltalk ffi squeak

我想处理像struct foo {char *name; char **fields ; size_t nfields};

这样的结构

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

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 *,这完全绕过了类型检查 - 不太理想......

知道如何正确处理这样的原型吗?

1 个答案:

答案 0 :(得分:1)

自从Compiler-mt.435开始,解析器将不再抱怨,而是回调到ExternalType>>asPointerToPointerType。参见source.squeak.org/trunk/Compiler-mt.435.diffsource.squeak.org/FFI/FFI-Kernel-mt.96.diff

在撰写本文时,此类指针对指针类型将被视为常规指针类型。因此,您将松散外部类型实际上指向指针数组的信息。

何时需要该信息?

  • 在通话期间在FFI插件中强制参数时
  • 在通话期间在FFI插件中构造返回的对象时
  • 从结构字段和FFI调用返回值解释ExternalData实例时
  • 在诸如对象资源管理器之类的工具中

吱吱声中已经有几种RawBitsArray。将StringExternalStructure(包括压缩或联合)添加到混合中,我们在Squeak中具有各种对象以映射最里面的维度(即,int *,char *,void *) 。 ExternalData可以代表多维数组的其他级别(即,int **,char **,void **等)。

因此,这里还有其他任务:

  1. 可以将指针尺寸信息存储为新的外部类型,以通过ExternalType>>referencedType找到。我们可能希望将新信息放入compiledSpec中。参见http://forum.world.st/FFI-Plugin-Question-about-multi-dimensional-arrays-e-g-char-int-void-td5118484.html
  2. 更新在ExternalArray中读取的值以解开一个指针在另一个指针之后;并让结构域访问器的代码生成器以类似的方式生成代码。
  3. 在插件中扩展参数强制以接受已经支持的数组(例如String等)