C语言绑定
crystal允许你直接调用现成的C库。此外,crystal还提供了像out, to_unsafe之类的操作,使用绑定是非常便利的。
Lib
lib声明了一组C函数和类型。
@[Link("pcre")]
lib LibPCRE
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库中存在大写开头的函数,可以像下面这样写:
lib LibSDL
fun init = SDL_Init(flags : UInt32) : Int32
end
如果名称不是有效的函数或类型,可以使用字符串的形式
lib LLVMIntrinsics
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之类的类型。
lib MyLib
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