Взаимодействие с C с помощью cinterop и файлов .def
Вызывайте библиотеки C из Kotlin/Native с помощью инструмента cinterop и файлов определений
«Взаимодействие с C с помощью cinterop и файлов .def» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.
Зачем нужна интеграция с C
Kotlin/Native может напрямую вызывать библиотеки C — без оболочек JNI и промежуточного слоя. Это позволяет использовать системные библиотеки платформы, драйверы оборудования и любые совместимые с C библиотеки из кода Kotlin, скомпилированного в нативные двоичные файлы.
Файл .def
Файл .def описывает импортируемую библиотеку C. В нём указываются заголовочные файлы, имя библиотеки и необязательные флаги компилятора и компоновщика. Поместите его в src/nativeInterop/cinterop/:
# src/nativeInterop/cinterop/libcurl.def
headers = curl/curl.h
headerFilter = curl/**
linkerOpts.linux = -lcurl
linkerOpts.macos = -lcurlРегистрация интеграции в Gradle
Укажите файл .def в блоке compilations цели:
kotlin {
linuxX64 {
compilations["main"].cinterops {
val libcurl by creating {
defFile(project.file("src/nativeInterop/cinterop/libcurl.def"))
}
}
}
}Запуск cinterop
Запустите ./gradlew cinteropLibcurlLinuxX64, чтобы сгенерировать .klib из заголовочных файлов C. Сгенерированные привязки Kotlin появятся в build/cinterop/ и автоматически будут добавлены в путь к классам компиляции.
Использование функций C в Kotlin
После генерации импортируйте пакет, объявленный в файле .def, и вызывайте функции C как функции Kotlin. Типы указателей представлены как CPointer:
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
}Закрепление объектов Kotlin для C
Чтобы передать адрес объекта Kotlin функции C (например, функции обратного вызова), закрепите его с помощью StableRef или Pinned, чтобы сборщик мусора не мог его переместить:
val stableRef = StableRef.create(myKotlinObject)
try {
c_function_expecting_user_data(stableRef.asCPointer())
} finally {
stableRef.dispose()
}Строки C и строки Kotlin
Преобразуйте String Kotlin и const char* C с помощью следующих средств:
"hello".cstr→ CValues, допустимо внутриmemScopedcPointer.toKString()→ строка Kotlin изCPointer<ByteVar>
memScoped {
val cStr = "Hello, C!".cstr.ptr // CPointer<ByteVar>
val back = cStr.toKString() // "Hello, C!"
}Доступ к структурам
Структуры C превращаются в классы Kotlin со свойствами. Получайте доступ к полям структуры с помощью оператора точки. Выделяйте структуры с помощью alloc внутри memScoped { }:
memScoped {
val addr = alloc<sockaddr_in>()
addr.sin_family = AF_INET.convert()
addr.sin_port = htons(8080u).convert()
}Встраивание кода C
Для коротких фрагментов C используйте блок cCode в файле .def, чтобы написать встроенный код 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), типы не совпадают (проверьте API сгенерированного .klib). Включите подробный вывод cinterop с помощью -verbose в файле def или в конфигурации задачи Gradle.
Проверка
Каково назначение memScoped { } во взаимодействии Kotlin/Native с C?
Итоги: взаимодействие с C с помощью cinterop и файлов .def
Главные выводы:
- Файл
.defзадаёт заголовочные файлы, параметры компоновщика и необязательный встроенный код C - Зарегистрируйте его в Gradle с помощью
cinterops { val name by creating { defFile(...) } } - Запустите задачу Gradle
cinterop<Name><Target>, чтобы сгенерировать привязки - Используйте
memScoped { }для временных нативных выделений памяти - Закрепляйте объекты, существующие длительное время, с помощью
StableRef; преобразуйте строки с помощью.cstr/.toKString()
Часто задаваемые вопросы
Урок «Взаимодействие с C с помощью cinterop и файлов .def» бесплатный?
Да — полный текст урока «Взаимодействие с C с помощью cinterop и файлов .def» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.
Чему я научусь в уроке «Взаимодействие с C с помощью cinterop и файлов .def»?
Вызывайте библиотеки C из Kotlin/Native с помощью инструмента cinterop и файлов определений Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Kotlin Academy?
Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Взаимодействие с C с помощью cinterop и файлов .def»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Kotlin Academy?
Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Обзор Kotlin/Native: цели, набор инструментов и компиляция
- Управление памятью в Kotlin/Native: новый MM
- Взаимодействие с C с помощью cinterop и файлов .def
- Kotlin/WASM: компиляция в WebAssembly для браузера