如何处理Squeak FFI中的typedef

时间:2018-04-11 20:21:12

标签: smalltalk ffi squeak

我想与一个库(HDF5)接口,它在函数原型和结构定义中都使用了自己的typedef。

typedef struct {
    H5L_type_t          type;           /* Type of link                   */
    hbool_t             corder_valid;   /* Indicate if creation order is valid */
    int64_t             corder;         /* Creation order                 */
    H5T_cset_t          cset;           /* Character set of link name     */
    union {
        haddr_t         address;        /* Address hard link points to    */
        size_t          val_size;       /* Size of a soft link or UD link value */
    } u;
} H5L_info_t;

在使用DLLCC的Visualworks中,我可以处理这样的typedef:

H5Interface>>hbool_t
    <C: typedef unsigned int hbool_t>

然后我可以在原型和结构中使用hbool_t,对于枚举也是如此。

但是Squeak FFI似乎只了解一些原子类型并将其他任何东西解释为结构。显然,有人必须进行翻译,如果它不是自动化的,那么它既错误,也不会对未来外部图书馆的演变具有鲁棒性。

那么避免这种脆弱性的推荐方法是什么?

2 个答案:

答案 0 :(得分:1)

似乎处理别名(typedef)

有一个模糊的功能

创建一个新的ExternalStructure类

ExternalStructure subclass: #'Hbool_t'
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'FFI-Tests'

然后使用nil和别名类型

创建fields方法
Hbool_t class>>fields
    ^#( nil 'ulong' )

Hbool_t defineFields和现在'Hbool_t'是注册类型,可以在其他结构定义和函数原型中使用。

这不完全是'hbool_t',但它比直接替换ulong更好。

答案 1 :(得分:1)

自mt.92起,您还可以继承ExternalTypeAlias的子类,以清晰的方式记录类型别名。参见source.squeak.org/FFI/FFI-Kernel-mt.92.diff

您的示例别名可以使用新的基类:

ExternalTypeAlias subclass: #'Hbool_t'
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'FFI-Tests'

类端只需要原始类型名称,这就是您要使用的别名:

Hbool_t class>>originalTypeName
    ^ 'ulong'

请注意,Hbool_t defineFields还将定义访问器#value#value:,以在运行时解析别名。

还请注意,具有使用该别名的字段的外部结构甚至会为原子类型的别名创建实例:

H5L_info_t>>corder_valid
    <generated>
    ^ Hbool_t fromHandle: (handle unsignedLongAt: 123456)