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



我想处理这样的结构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。将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等)

最新更新