0Pricing
Kotlin Academy · 강의

cinterop 및 .def 파일을 사용한 C 상호 운용

cinterop 도구와 정의 파일을 사용해 Kotlin/Native에서 C 라이브러리를 호출합니다.

cinterop 및 .def 파일을 사용한 C 상호 운용은(는) CoddyKit의 무료 Kotlin Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Kotlin Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Kotlin Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

C 상호 운용성은 왜 필요한가요

Kotlin/Native는 C 라이브러리를 직접 호출할 수 있으므로 JNI 래퍼나 브리지 계층이 필요하지 않습니다. 이를 통해 네이티브 바이너리로 컴파일된 Kotlin 코드에서 플랫폼 시스템 라이브러리, 하드웨어 드라이버 또는 C 호환 라이브러리를 사용할 수 있습니다.

.def 파일

.def 파일은 가져올 C 라이브러리를 설명합니다. 헤더, 라이브러리 이름, 선택적 컴파일러/링커 플래그를 지정합니다. 다음 위치에 배치하십시오: src/nativeInterop/cinterop/

# src/nativeInterop/cinterop/libcurl.def
headers = curl/curl.h
headerFilter = curl/**
linkerOpts.linux = -lcurl
linkerOpts.macos = -lcurl

Gradle에 상호 운용성 등록하기

대상의 compilations 블록에서 .def 파일을 참조하십시오:

kotlin {
    linuxX64 {
        compilations["main"].cinterops {
            val libcurl by creating {
                defFile(project.file("src/nativeInterop/cinterop/libcurl.def"))
            }
        }
    }
}

cinterop 실행

C 헤더로부터 .klib를 생성하려면 ./gradlew cinteropLibcurlLinuxX64를 실행합니다. 생성된 Kotlin 바인딩은 build/cinterop/에 나타나며 컴파일 클래스 경로에 자동으로 추가됩니다.

Kotlin에서 C 함수 사용하기

생성한 후에는 .def 파일에 선언된 패키지를 가져오고 C 함수를 Kotlin 함수처럼 호출합니다. 포인터 타입은 CPointer<T>로 표현됩니다:

import libcurl.*
import kotlinx.cinterop.*

fun fetchUrl(url: String): String = memScoped {
    val handle = curl_easy_init() ?: error("curl init failed")
    curl_easy_setopt(handle, CURLOPT_URL, url.cstr.ptr)
    curl_easy_perform(handle)
    curl_easy_cleanup(handle)
    "done"
}

memScoped: 스택에 할당되는 메모리

memScoped { }는 네이티브 할당(alloc(), allocArray())이 블록을 벗어날 때 자동으로 해제되는 메모리 범위를 만듭니다. 메모리 누수를 방지하려면 임시 C 메모리에 항상 사용해야 합니다.

memScoped {
    val value = alloc<IntVar>()
    value.value = 42
    println(value.value)  // 42
    // freed automatically at end of memScoped
}

C를 위한 Kotlin 객체 고정하기

Kotlin 객체의 주소를 C 함수(예: 콜백)에 전달하려면 가비지 컬렉터가 객체를 이동하지 못하도록 StableRef 또는 Pinned로 고정합니다:

val stableRef = StableRef.create(myKotlinObject)
try {
    c_function_expecting_user_data(stableRef.asCPointer())
} finally {
    stableRef.dispose()
}

C 문자열과 Kotlin 문자열

다음을 사용하여 Kotlin String과 C const char* 사이를 변환합니다:

  • "hello".cstr → CValues, memScoped 안에서 유효함
  • cPointer.toKString() → CPointer<ByteVar>에서 Kotlin String으로 변환
memScoped {
    val cStr = "Hello, C!".cstr.ptr   // CPointer<ByteVar>
    val back = cStr.toKString()         // "Hello, C!"
}

구조체 접근

C 구조체는 속성을 가진 Kotlin 클래스로 변환됩니다. 점 연산자를 사용하여 구조체 필드에 접근합니다. memScoped { } 안에서 alloc<StructName>()으로 구조체를 할당합니다:

memScoped {
    val addr = alloc<sockaddr_in>()
    addr.sin_family = AF_INET.convert()
    addr.sin_port = htons(8080u).convert()
}

인라인 C 코드 삽입

짧은 C 코드를 작성할 때는 .def 파일의 cCode 블록을 사용합니다. 이 블록의 인라인 C 코드는 바인딩과 함께 컴파일됩니다:

# In .def file
headers = stdio.h
---
// Inline C code after ---
static inline int add(int a, int b) { return a + b; }

C 상호 운용 문제 디버깅

일반적인 문제는 다음과 같습니다. 헤더가 누락된 경우(headerFilter 확인), 링커 플래그가 누락된 경우(linkerOpts 추가), 타입이 일치하지 않는 경우(생성된 .klib API 확인)입니다. def 파일 또는 Gradle 작업 구성에서 -verbose를 사용하여 cinterop의 상세 출력을 활성화합니다.

빠른 확인

Kotlin/Native C 상호 운용에서 memScoped { }는 어떤 용도로 사용되나요?

cinterop 및 .def 파일을 사용한 C 상호 운용 요약

핵심 요점:

  • .def 파일은 헤더, 링커 옵션 및 선택적 인라인 C 코드를 지정합니다
  • cinterops { val name by creating { defFile(...) } }를 통해 Gradle에 등록합니다
  • cinterop<Name><Target> Gradle 작업을 실행하여 바인딩을 생성합니다
  • 임시 네이티브 할당에는 memScoped { }를 사용합니다
  • 수명이 긴 객체는 StableRef로 고정하고, 문자열은 .cstr / .toKString()으로 변환합니다

자주 묻는 질문

“cinterop 및 .def 파일을 사용한 C 상호 운용” 강의는 무료인가요?

네 — “cinterop 및 .def 파일을 사용한 C 상호 운용” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Kotlin Academy 강의 전체를 잠금 해제할 수 있습니다. Kotlin Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“cinterop 및 .def 파일을 사용한 C 상호 운용”에서 뭘 배우나요?

cinterop 도구와 정의 파일을 사용해 Kotlin/Native에서 C 라이브러리를 호출합니다. 브라우저에서 직접 실행하는 실습 코드로 Kotlin Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Kotlin Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Kotlin Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“cinterop 및 .def 파일을 사용한 C 상호 운용” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Kotlin Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Kotlin Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. Kotlin/Native 개요: 대상, 도구 모음 및 컴파일
  2. Kotlin/Native의 메모리 관리: 새로운 MM
  3. cinterop 및 .def 파일을 사용한 C 상호 운용
  4. Kotlin/WASM: 브라우저용 WebAssembly 컴파일
← Kotlin Academy(으)로 돌아가기