fun
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_... 메서드를 쓸 수 있어요.
함수 이름 (Function names)
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 바인딩에서의 타입 (Types in C Bindings)
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 struct
fun 타입의 표기법은 type grammar를 참고하세요.
표준 라이브러리는 int, short, size_t 같은 흔한 C 타입의 별칭을 담은 LibC lib을 정의해요. 바인딩에서 이렇게 쓰세요:
lib MyLib
fun my_fun(some_size : LibC::SizeT)
end
NOTE: C의 char 타입은 Crystal에서 UInt8이에요. 그래서 char*나 const char*는 UInt8*예요. Crystal의 Char 타입은 유니코드 코드포인트라 4바이트로 표현돼서, UInt8이 아니라 Int32에 가까워요. 헷갈리면 LibC::Char 별칭도 있어요.
출처: Crystal 공식 문서
더 알아보기 (Learn more)
- fun 타입 표기법은 type grammar를 함께 보세요.