C语言绑定
crystal允许你直接调用现成的C库。此外,crystal还提供了像out, to_unsafe之类的操作,使用绑定是非常便利的。
Lib
lib声明了一组C函数和类型。@[Link("pcre")]
libLibPCRE
end
一个lib的名称通常以Lib开头, 但不是强制的。属性用来传递标志给连接器, 用于查找外部库。@[Link("pcre")]将会传递 -lpcre给连接器,但是连接器会优先尝试pkg-config 。@[Link(ldflags: "…")]将会不作修改直接传递这些标志给连接器,如@[Link(ldflags: "-lpcre")]。这里还有一个使用反引号的技巧, 如
@[Link(ldflags: "pkg-config libpcre —libs")]
@[Link(framework: "Cocoa")]将传递 -framework Cocoa 到连接器 (only useful in Mac OS X).
fun
fun用于在lib内部定义一个C绑定函数。lib C
# In C: double cos(double x)
fun cos(value:Float64):Float64
end
一旦绑定成功,函数就在C类型内部生效 ,使用就像是调用一个类的方法一样。C.cos(1.5)#=> 0.0707372
如果函数没有参数 ,可以省略括号。lib C
fun getch:Int32
end
C.getch
如果函数没有返回 ,则返回类型也可以省略。lib C
fun srand(seed:UInt32)
end
C.srand(1_u32)
绑定可变参数的函数lib X
fun variadic(value:Int32,...):Int32
end
X.variadic(1,2,3,4)
注意:调用C绑定函数必须要正确声明参数类型。
因为crystal的函数必须用小写开头,所以在使用fun时也必须采用小写 。如果C库中存在大写开头的函数,可以像下面这样写:libLibSDL
fun init=SDL_Init(flags:UInt32):Int32
end
如果名称不是有效的函数或类型,可以使用字符串的形式libLLVMIntrinsics
fun ceil_f32="llvm.ceil.f32"(value:Float32):Float32
end
可以用于C绑定的数据类型有: 1. Primitive types (Int8, …, Int64, UInt8, …, UInt64, Float32, Float64)Pointer types (Pointer(Int32), which can also be written as Int32*)
Static arrays (StaticArray(Int32, 8), which can also be written as Int32[8])
Function types (Function(Int32, Int32), which can also be written as Int32 -> Int32)
Other struct, union, enum, type or alias declared previously.
Void: the absence of a return value.
NoReturn: similar to Void, but the compiler understands that no code can be executed after that invocation.
Crystal structs marked with the @[Extern] attribute
标准库定义了LibC作为C类型的别名,比如有像int, short, size_t之类的类型。libMyLib
fun my_fun(some_size:LibC::SizeT)
end
注意: C的char在crystal中是UInt8, 所以const char或char是 UInt8 。The Char type in Crystal is a unicode codepoint so it is represented by four bytes, making it similar to an Int32, not to an UInt8. There's also the alias LibC::Char if in doubt.
//todo