A fun declaration inside a lib binds to a C function.

lib C
  # In C: double cos(double x)
  fun cos(value : Float64) : Float64

Once you bind it, the function is available inside the C type as if it was a class method:

C.cos(1.5) #=> 0.0707372

You can omit the parentheses if the function doesn't have arguments (and omit them in the call as well):

lib C
  fun getch : Int32


If the return type is void you can omit it:

lib C
  fun srand(seed : UInt32)


You can bind to variadic functions:

lib X
  fun variadic(value : Int32, ...) : Int32

X.variadic(1, 2, 3, 4)

Note that there are no implicit conversions (except to_unsafe, which is explained later) when invoking a C function: you must pass the exact type that is expected. For integers and floats you can use the various to_... methods.

Because method names in Crystal must start with a lowercase letter, fun names must also start with a lowercase letter. If you need to bind to a C function that starts with a capital letter you can give the function another name for Crystal:

lib LibSDL
  fun init = SDL_Init(flags : UInt32) : Int32

You can also use a string as a name if the name is not a valid identifier or type name:

lib LLVMIntrinsics
  fun ceil_f32 = "llvm.ceil.f32"(value : Float32) : Float32

This can also be used to give shorter, nicer names to C functions, as these tend to be long and are usually prefixed with the library name.

The valid types to use in C bindings are:

  • 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

Refer to the type grammar for the notation used in fun types.

The standard library defines the LibC lib with aliases for common C types, like int, short, size_t. Use them in bindings like this:

lib MyLib
  fun my_fun(some_size : LibC::SizeT)

Note: The C char type is UInt8 in Crystal, so a char* or a const char* is 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.

results matching ""

    No results matching ""