cinteropと.defファイルによるC相互運用
cinteropツールと定義ファイルを使用して、Kotlin/NativeからCライブラリを呼び出します。
「cinteropと.defファイルによるC相互運用」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
C相互運用が必要な理由
Kotlin/Native では、JNI ラッパーやブリッジングレイヤーを介さずに C ライブラリを直接呼び出せます。これにより、Kotlin コードから、プラットフォームのシステムライブラリ、ハードウェアドライバー、その他の C 互換ライブラリを、ネイティブバイナリにコンパイルして利用できます。
.defファイル
.def ファイルには、インポートする C ライブラリの情報を記述します。ヘッダー、ライブラリ名、オプションのコンパイラ/リンカーフラグを指定します。src/nativeInterop/cinterop/ に配置してください:
# src/nativeInterop/cinterop/libcurl.def
headers = curl/curl.h
headerFilter = curl/**
linkerOpts.linux = -lcurl
linkerOpts.macos = -lcurlGradleに相互運用を登録する
ターゲットの 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関数(コールバックなど)に渡すには、GCによってオブジェクトが移動されないように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()で変換します
AI チューターと学ぶ Kotlin — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 51
- レッスン
- 203
よくある質問
「cinteropと.defファイルによるC相互運用」レッスンは無料ですか?
はい。「cinteropと.defファイルによるC相互運用」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「cinteropと.defファイルによるC相互運用」で何を学びますか?
cinteropツールと定義ファイルを使用して、Kotlin/NativeからCライブラリを呼び出します。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「cinteropと.defファイルによるC相互運用」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Kotlin/Nativeの概要:ターゲット、ツールチェーン、コンパイル
- Kotlin/Nativeのメモリ管理:新しいMM
- cinteropと.defファイルによるC相互運用
- Kotlin/WASM:ブラウザー向けWebAssemblyへのコンパイル