Kotlin Academy · บทเรียน

การเชื่อมต่อกับ C ด้วย cinterop และไฟล์ .def

เรียกใช้ไลบรารี C จาก Kotlin/Native โดยใช้เครื่องมือ cinterop และไฟล์คำจำกัดความ

บทเรียน 3 จาก 413 ขั้นตอน

การเชื่อมต่อกับ C ด้วย cinterop และไฟล์ .def เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดจึงต้องใช้การทำงานร่วมกับ C

Kotlin/Native สามารถเรียกใช้ไลบรารี C ได้โดยตรง — ไม่ต้องมีตัวห่อหุ้ม JNI หรือชั้นเชื่อมต่อ วิธีนี้ทำให้สามารถใช้ไลบรารีระบบของแพลตฟอร์ม ไดรเวอร์ฮาร์ดแวร์ หรือไลบรารีที่เข้ากันได้กับ C จากโค้ด Kotlin ที่คอมไพล์เป็นไบนารีเนทีฟ

ไฟล์ .def

ไฟล์ .def ใช้อธิบายไลบรารี C ที่จะนำเข้า โดยระบุ headers ชื่อไลบรารี และแฟล็กของคอมไพเลอร์/ตัวเชื่อมโยงที่เป็นตัวเลือก วางไฟล์ไว้ใน 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 ซึ่งใช้ได้ภายใน memScoped
  • cPointer.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()
เริ่มต้นได้ฟรี

เรียนรู้ Kotlin ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
51
บทเรียน
203

คำถามที่พบบ่อย

บทเรียน “การเชื่อมต่อกับ C ด้วย cinterop และไฟล์ .def” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเชื่อมต่อกับ C ด้วย cinterop และไฟล์ .def” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การเชื่อมต่อกับ C ด้วย cinterop และไฟล์ .def”

เรียกใช้ไลบรารี C จาก Kotlin/Native โดยใช้เครื่องมือ cinterop และไฟล์คำจำกัดความ คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การเชื่อมต่อกับ C ด้วย cinterop และไฟล์ .def” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม

ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ภาพรวม Kotlin/Native: เป้าหมาย ชุดเครื่องมือ และการคอมไพล์
  2. การจัดการหน่วยความจำใน Kotlin/Native: MM ใหม่
  3. การเชื่อมต่อกับ C ด้วย cinterop และไฟล์ .def
  4. Kotlin/WASM: การคอมไพล์เป็น WebAssembly สำหรับเบราว์เซอร์
← กลับไปที่ Kotlin Academy