コンテンツにスキップ

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 とも表記できます)
  • 以前に宣言されたその他の structunionenumtype、または alias
  • Void: 戻り値がないことを示します。
  • NoReturn: Void と似ていますが、コンパイラはその呼び出しの後でコードを実行できないことを理解します。
  • @[Extern] アノテーションが付いた Crystal 構造体

fun 型で使用される表記法については、型文法 を参照してください。

標準ライブラリは、intshortsize_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 もあります。