從 C 語言映射基本資料型別 – 教學
這是映射 Kotlin 與 C 教學系列的第一部分。
從 C 語言映射基本資料型別
從 C 語言映射結構與聯集型別
映射函式指標
從 C 語言映射字串
C 語言函式庫匯入功能處於 Beta 階段。由 cinterop 工具從 C 函式庫生成的 Kotlin 宣告應具有
@ExperimentalForeignApi
註解。Kotlin/Native 隨附的原生平台函式庫(例如 Foundation、UIKit 和 POSIX)僅需要針對某些 API 選擇加入。
讓我們探索哪些 C 資料型別在 Kotlin/Native 中可見,反之亦然,並探討 Kotlin/Native 和 多平台 Gradle 建構中與 C interop 相關的進階用例。
在本教學中,您將:
您可以使用命令列來生成 Kotlin 函式庫,無論是直接生成還是透過腳本檔案(例如 .sh
或 .bat
檔案)。然而,這種方法不適用於擁有數百個檔案和函式庫的大型專案。使用建構系統可透過下載並快取 Kotlin/Native 編譯器二進位檔和具有轉譯相依性的函式庫,以及執行編譯器和測試來簡化過程。Kotlin/Native 可以透過 Kotlin 多平台外掛程式 使用 Gradle 建構系統。
C 語言中的型別
C 程式語言具有以下 資料型別:
- 基本型別:
char, int, float, double
以及修飾符signed, unsigned, short, long
- 結構、聯集、陣列
- 指標
- 函式指標
還有更特定的型別:
C 語言中還有以下型別限定符:const
、volatile
、restrict
、atomic
。
讓我們看看哪些 C 資料型別在 Kotlin 中可見。
建立 C 函式庫
在本教學中,您不會建立 lib.c
原始檔,這只在您想要編譯並執行您的 C 函式庫時才需要。對於此設定,您只需要一個執行 cinterop 工具 所需的 .h
標頭檔。
cinterop 工具會為每組 .h
檔案生成一個 Kotlin/Native 函式庫(一個 .klib
檔案)。生成的函式庫有助於橋接從 Kotlin/Native 到 C 的呼叫。它包含與 .h
檔案中的定義相對應的 Kotlin 宣告。
建立 C 函式庫:
為您未來的專案建立一個空資料夾。
在其中,建立一個
lib.h
檔案,其中包含以下內容,以查看 C 函式如何映射到 Kotlin:c#ifndef LIB2_H_INCLUDED #define LIB2_H_INCLUDED void ints(char c, short d, int e, long f); void uints(unsigned char c, unsigned short d, unsigned int e, unsigned long f); void doubles(float a, double b); #endif
該檔案沒有
extern "C"
區塊,本範例不需要它,但如果您使用 C++ 和重載函式,則可能需要。請參閱此 Stackoverflow 討論串 以獲取更多詳細資訊。建立
lib.def
定義檔,其中包含以下內容:cheaders = lib.h
將巨集或其他 C 定義包含在由 cinterop 工具生成的程式碼中會很有幫助。這樣,方法主體也會被編譯並完全包含在二進位檔中。藉由這項功能,您可以建立一個可執行的範例而不需要 C 編譯器。
為此,請在
---
分隔符之後,將lib.h
檔案中的 C 函式實作新增到新的interop.def
檔案中:c--- void ints(char c, short d, int e, long f) { } void uints(unsigned char c, unsigned short d, unsigned int e, unsigned long f) { } void doubles(float a, double b) { }
interop.def
檔案提供了所有必要的內容,以便編譯、執行或在 IDE 中開啟應用程式。
建立 Kotlin/Native 專案
有關詳細的入門步驟以及如何建立新的 Kotlin/Native 專案並在 IntelliJ IDEA 中開啟它的說明,請參閱 Kotlin/Native 入門 教學。
建立專案檔案:
在您的專案資料夾中,建立一個
build.gradle(.kts)
Gradle 建構檔案,其中包含以下內容:kotlinplugins { kotlin("multiplatform") version "2.2.10" } repositories { mavenCentral() } kotlin { macosArm64("native") { // Apple Silicon 上的 macOS // macosX64("native") { // x86_64 平台上的 macOS // linuxArm64("native") { // ARM64 平台上的 Linux // linuxX64("native") { // x86_64 平台上的 Linux // mingwX64("native") { // 在 Windows 上 val main by compilations.getting val interop by main.cinterops.creating binaries { executable() } } } tasks.wrapper { gradleVersion = "8.14" distributionType = Wrapper.DistributionType.BIN }
groovyplugins { id 'org.jetbrains.kotlin.multiplatform' version '2.2.10' } repositories { mavenCentral() } kotlin { macosArm64("native") { // Apple Silicon macOS // macosX64("native") { // x86_64 平台上的 macOS // linuxArm64("native") { // ARM64 平台上的 Linux // linuxX64("native") { // x86_64 平台上的 Linux // mingwX64("native") { // Windows compilations.main.cinterops { interop } binaries { executable() } } } wrapper { gradleVersion = '8.14' distributionType = 'BIN' }
專案檔案將 C interop 配置為一個額外的建構步驟。請查看 多平台 Gradle DSL 參考 以了解不同的配置方式。
將您的
interop.def
、lib.h
和lib.def
檔案移動到src/nativeInterop/cinterop
目錄。建立
src/nativeMain/kotlin
目錄。這裡就是您應該放置所有原始檔的地方,遵循 Gradle 關於使用約定而非配置的建議。預設情況下,所有來自 C 的符號都會匯入到
interop
套件中。在
src/nativeMain/kotlin
中,建立一個hello.kt
骨架檔案,其中包含以下內容:kotlinimport interop.* import kotlinx.cinterop.ExperimentalForeignApi @OptIn(ExperimentalForeignApi::class) fun main() { println("Hello Kotlin/Native!") ints(/* fix me*/) uints(/* fix me*/) doubles(/* fix me*/) }
稍後您將完成程式碼,當您了解 C 基本型別宣告在 Kotlin 端如何呈現時。
檢查 C 函式庫生成的 Kotlin API
讓我們看看 C 基本型別是如何映射到 Kotlin/Native 的,並相應地更新範例專案。
使用 IntelliJ IDEA 的 前往宣告 命令(/)導航到以下為 C 函式生成的 API:
fun ints(c: kotlin.Byte, d: kotlin.Short, e: kotlin.Int, f: kotlin.Long)
fun uints(c: kotlin.UByte, d: kotlin.UShort, e: kotlin.UInt, f: kotlin.ULong)
fun doubles(a: kotlin.Float, b: kotlin.Double)
C 型別是直接映射的,除了 char
型別,它被映射到 kotlin.Byte
,因為它通常是一個 8 位元有符號值:
C | Kotlin |
---|---|
char | kotlin.Byte |
unsigned char | kotlin.UByte |
short | kotlin.Short |
unsigned short | kotlin.UShort |
int | kotlin.Int |
unsigned int | kotlin.UInt |
long long | kotlin.Long |
unsigned long long | kotlin.ULong |
float | kotlin.Float |
double | kotlin.Double |
更新 Kotlin 程式碼
現在您已經看到了 C 定義,您可以更新您的 Kotlin 程式碼了。hello.kt
檔案中的最終程式碼可能如下所示:
import interop.*
import kotlinx.cinterop.ExperimentalForeignApi
@OptIn(ExperimentalForeignApi::class)
fun main() {
println("Hello Kotlin/Native!")
ints(1, 2, 3, 4)
uints(5u, 6u, 7u, 8u)
doubles(9.0f, 10.0)
}
要驗證一切是否按預期運作,請在您的 IDE 中執行 runDebugExecutableNative
Gradle 任務,或使用以下命令執行程式碼:
./gradlew runDebugExecutableNative
下一步
在本系列的下一部分中,您將學習結構和聯集型別如何在 Kotlin 和 C 之間映射:
參見
在 與 C 的互通性 文件中了解更多,其中涵蓋了更進階的場景。