التكامل مع 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→ قيم C، صالحة داخل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؛ وأنواع غير متطابقة، فتحقّق من واجهة برمجة التطبيقات في .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 يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- نظرة عامة على Kotlin/Native: الأهداف وسلسلة الأدوات والترجمة
- إدارة الذاكرة في Kotlin/Native: مدير الذاكرة الجديد
- التكامل مع C باستخدام cinterop وملفات .def
- Kotlin/WASM: الترجمة إلى WebAssembly للمتصفح