例如,此代码无法编译
def double
x * x
end
lib LibC
# Error
def double
x * x
end
end
我知道我们可以使用模块,但是我们不能使用与模块和lib相同的LibC名称
lib LibC
end
module LibC
def double
x * x
end
end
这个问题有解决方案吗?
答案 0 :(得分:4)
为什么这对您来说是个问题? :)
lib
定义到外部库的绑定。从技术上讲,它是通过定义链接器将解析的外部符号的功能签名来实现的。此外,它还允许使用C ABI语义定义结构,将外部库接口中使用的一系列常量映射为有用的分组和别名的枚举,以使在绑定定义中将Crystal类型映射为C类型更加容易。
绑定库时,此低级lib
定义永远不会成为绑定用户的最终结果!相反,您应该至少定义一个薄包装器,以将外部API转换为更惯用的Crystal版本。
因此,假设我们正在编写虚构的libsaucepan的绑定,您将以lib
定义开始,也许像这样:
@[Link("saucepan")]
lib LibSaucepan
alias Pan = Void*
fun aquire : Pan
fun add_water(pan : Pan, ml : LibC::Int)
fun cook(pan : Pan)
fun is_done(pan : Pan) : LibC::Int
end
您不会在这里停下来,但可以创建一个包装API的类:
class Saucepan
def initialize
@pan = LibSaucepan.aquire
end
def add_water(ml : Int)
LibSaucepan.add_water(@pan, LibC::Int.new(ml))
end
def done?
LibSaucepan.is_done(@pan) == 1
end
def cook
LibSaucepan.cook(@pan)
until done?
sleep 1
end
end
def heat_water(ml : Int)
add_water(ml)
cook
end
end
您可以在此包装器中放置任何辅助方法:)