fun¶
lib 内の fun 宣言は、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
戻り値の型が void の場合は、省略できます。
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 関数を呼び出す際には、暗黙の型変換(後述する to_unsafe を除く)は行われません。期待される型と完全に一致する型を渡す必要があります。整数と浮動小数点数には、さまざまな to_... メソッドを使用できます。
関数名¶
lib 定義の関数名は、大文字で始めることができます。これは、小文字で始める必要がある lib の外部のメソッドや関数定義とは異なります。
Crystal の関数名は、C の名前と異なる場合があります。次の例は、C 関数名 SDL_Init を Crystal で LibSDL.init としてバインドする方法を示しています。
lib LibSDL
fun init = SDL_Init(flags : UInt32) : Int32
end
有効な識別子ではない名前を記述できるように、C の名前を引用符で囲むことができます。
lib LLVMIntrinsics
fun ceil_f32 = "llvm.ceil.f32"(value : Float32) : Float32
end
これはまた、C 関数に短くて見栄えの良い名前を付けるためにも使用できます。C 関数は長くなりがちで、通常はライブラリ名でプレフィックスが付けられています。
Cバインディングでの型¶
C バインディングで使用できる有効な型は次のとおりです。
- プリミティブ型 (
Int8, ...,Int64,UInt8, ...,UInt64,Float32,Float64) - ポインタ型 (
Pointer(Int32)、Int32*とも表記できます) - 静的配列 (
StaticArray(Int32, 8)、Int32[8]とも表記できます) - 関数型 (
Proc(Int32, Int32)、Int32 -> Int32とも表記できます) - 以前に宣言されたその他の
struct、union、enum、type、またはalias。 Void: 戻り値がないことを示します。NoReturn:Voidと似ていますが、コンパイラはその呼び出しの後でコードを実行できないことを理解します。@[Extern]アノテーションが付いた Crystal 構造体
fun 型で使用される表記法については、型文法 を参照してください。
標準ライブラリは、int、short、size_t などの一般的な C 型のエイリアスを持つ LibC lib を定義しています。バインディングでは、次のように使用します。
lib MyLib
fun my_fun(some_size : LibC::SizeT)
end
注意
C の char 型は Crystal では UInt8 です。そのため、char* または const char* は UInt8* になります。Crystal の Char 型は Unicode コードポイントであるため、4 バイトで表され、UInt8 ではなく Int32 に似ています。疑問がある場合は、エイリアス LibC::Char もあります。