ger*_*era 7 smalltalk squeak ffi
我正在为现有的库编写一个FFI接口(用C语言编写).
该库使用了大量不透明结构,因此我定义了一些ExternalStructures(没有字段)用作void*.
现在我已经看到了两种与库连接的方式(或四种方式):
有一个ExternalLibrary与每个导出函数的方法:这可能会在实例类的方法,然后使用一个单例模式有一个实例.或者使用"更复杂"的语法实现类侧的方法,包括moduleNameFFI编译指示,如:
ffiTestFloats: f1 with: f2
"FFITestLibrary ffiTestFloats: $A with: 65.0"
<cdecl: float 'ffiTestFloats' (float float) module:'SqueakFFIPrims'>
^self externalCallFailed
Run Code Online (Sandbox Code Playgroud)
什么更好?
另外,我已经看到了这样做的其他方式,根本没有ExternalLibrary,并直接在实现方法ExternalStructure.我更喜欢第二部分,但是,所有FFI接口定义都通过几个类传播,维护和移植到其他平台,Smalltalk方言或库版本可能更复杂.
那么,做到这一点的"正确"方式是什么?
我会坚持按事物本来的样子建模的传统方法。我们这里有一个外部库,然后让我们为它创建一个类并在我们的对象中复制它的 API,当然,使用执行所需 FFI 调用的实例端方法。
我们已经使用这种方法二十年了,经验表明单例模式在这种情况下非常有效,因为它使客户的生活变得轻松。当然,必须小心处理此功能,以便您不会从不适当的位置引用库实例。但请注意,这不是一个重要的决定,但您必须以某种方式将库的唯一实例存储在某处。
在所涉及的外部结构中实现 FFI 调用并不自然,因为某些调用可能涉及多个结构或根本不涉及任何结构。那么,你会把它们放在哪里?
您还提到了在类方面实现方法的想法。毕竟,我们都同意每个库应该只有一个实例,不是吗?放弃这种可能性的一个原因是类端方法将提供不太灵活的实现。为什么?因为一件事是使用某种机制只拥有该类的一个实例,另一件事是使其不可能拥有它。如果您的对象是一个实例(而不是类),您仍然有可能避免明确鼓励的单个实例的限制,并能够创建另一个实例。这会违反您自己的规则,但能够这样做总是更好。想要做到这一点的一个简单情况就是测试。您可以创建第二个实例,该实例连接到库的另一个版本,并对其进行测试,而无需修改该类。不选择类端方法的另一个原因更加微妙:类代表事物的概念,而不是事物本身。因此,它们的自然协议与其实例的协议不同。两个接口的分离将使您的设计更加清晰。
| 归档时间: |
|
| 查看次数: |
104 次 |
| 最近记录: |