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
Если возвращаемый тип — 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 и именем LibSDL.init в Crystal.
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 допустимо использовать следующие типы:
- Примитивные типы (
Int8, ...,Int64,UInt8, ...,UInt64,Float32,Float64) - Типы указателей (
Pointer(Int32), который также можно записать какInt32*) - Статические массивы (
StaticArray(Int32, 8), который также можно записать какInt32[8]) - Типы функций (
Function(Int32, Int32), который также можно записать какInt32 -> Int32) - Другие ранее объявленные
struct,union,enum,typeилиalias. -
Void: отсутствие возвращаемого значения. -
NoReturn: аналогVoid, но компилятор понимает, что после этого вызова не может выполняться код. - Структуры Crystal, помеченные аннотацией
@[Extern]
Обозначения, используемые в типах fun, см. в грамматике типов.
Стандартная библиотека определяет библиотеку LibC с псевдонимами для распространенных типов C, таких как int, short, size_t. Используйте их в привязках следующим образом:
lib MyLib
fun my_fun(some_size : LibC::SizeT)
end
Примечание
Тип C char в Crystal — это UInt8, поэтому char* или const char* — это UInt8*. Тип Char в Crystal представляет кодовую точку Юникода, поэтому занимает четыре байта и похож на Int32, а не на UInt8. Если вы сомневаетесь, можно также использовать псевдоним LibC::Char.
To the extent possible under law, the persons who contributed to this workhave waived
all copyright and related or neighboring rights to this workby associating CC0 with it.
https://crystal-lang.org/reference/1.2/syntax_and_semantics/c_bindings/fun.html