
تتناول هذه المقالة أكثر الطرق السذاجة والأسهل لإنشاء امتداد PHP باستخدام Kotlin Native. ألفت انتباهكم إلى حقيقة أنه ليس
مع الاستخدام ولكن
مع الاستخدام .
بل هو نوع من البرنامج التعليمي مع وصف للمشاكل التي نشأت عند عبور القنفذ مع القنفذ وطرق حلها. لن يكون هناك وحي ، ولكن ربما يكون شخص ما في متناول اليد.
لذا ، إذا كنت مهتمًا ، فمرحبًا بالقط.
الهدف هو كتابة ملحق بوظيفة واحدة `` hello ($ name) `تأخذ سلسلة وتطبع` Hello ، $ name! `.
سنقرر بسذاجة ، كما يقول الاسم.
- دعونا نكتب دالة على Kotlin
- ترجمة في المكتبة المشتركة
- بالطريقة الكلاسيكية (في C) ، نكتب امتدادًا سيعيد توجيه استدعاء دالة إلى هذه المكتبة
يبدو الأمر بسيطًا ، لكن أشعل النار تكمن بالفعل في العشب الكثيف:
- هناك عدد من الأمثلة على استخدام مكتبات C في Kotlin ، لكنني لم أجد أي شيء مناسب لاستخدام وظائف مكتبة Kotlin في لغة C (حسنًا ، ربما كنت أبحث بشكل سيء ، ما هو حقًا)
- يقوم مترجم kotlinc بتحميل التبعيات في المرة الأولى التي يبدأ فيها. لكن الحظ السيئ هو جهاز Linux الافتراضي الخاص بي في سحابة الشركة. بدون القدرة ، حتى النظرية ، على الوصول إلى الإنترنت.
- هذه أشعل النار على الأرجح بسبب قلة الخبرة في لغة C ، لكنني سأخبرك كيف استغلني الرابط بشكل ملحوظ.
حدث كل شيء في إصدار Red Hat Enterprise Linux Server 7.5.دعنا نذهب!
للبدء ، قم بتثبيت ... لا ، ليس مترجم Kotlin. أولاً ، قم بتثبيت JDK. حسنا هكذا.
ثم قم بتثبيت مترجم Kotlin. ما عليك سوى تنزيل
الأرشيف من github وفك ضغطه ، على سبيل المثال ، إلى الدليل الرئيسي.
في عالم مثالي ، في البداية ، قام بتنزيل جميع التبعيات بنفسه ، ولكن في غياب الإنترنت ، نتابع على النحو التالي (يتم الحصول على المعرفة السرية في فترة قصيرة من موظفي JetBrains):
- ننشئ أي نص برمجي بسيط لـ Kotlin بحيث يكون هناك شيء يجب أن يزيله المترجم في الخطوة التالية
- نبدأ $ KOTLIN_HOME / bin / kotlinc SimpleScript.kt ، انتظر قليلاً واضغط CTRL + C - هذا لإنشاء بنية مجلد في الدليل الرئيسي
- نحن نبحث في الملف $ KOTLIN_HOME / konan / konan.properties ، في القسم الخاص بهندستنا المعمارية ، ونبحث عن العنصر:
dependencies.linux_x64 = \ clang-llvm-5.0.0-linux-x86-64 \ target-gcc-toolchain-3-linux-x86-64 \ libffi-3.2.1-2-linux-x86-64
- نذهب إلى مستودع خاص ونقوم بتنزيل كل ما سبق.
- نضيف كل هذا إلى ~ / .konan / cache (أذكرك بأن دليل لينكس الرئيسي هو التلدة)
الآن ، في البداية ، سيستخدم المترجم هذه التوزيعات ولن يدخل على الإنترنت.
يرجى ملاحظة أن التبعيات ليست صغيرة الحجم للغاية ، وبعد تثبيتها ، أصبح دليل بيتي أثقل بـ 3.4 غيغابايت. بالنسبة لأولئك الذين لديهم حجم منفصل تحت واجباتهم المنزلية ، يمكن أن يكون حرجًا.
بعد ذلك ، مع مدير الحزم القياسي ، قم بتثبيت php و php-devel المقابل.
في هذا الصدد ، انتهت الإجراءات التحضيرية.
نظرًا لأنه لا يستحق الحديث عن كتابة امتدادات PHP ، فسننتقل إلى أقصر رمز ممكن.
لنبدأ مع Kotlin
hellokt.kt fun kt_print(string:String){ println("Hello, $string!!!") }
في العديد من الأدلة والبرامج التعليمية ، يتم استخدام kotlinc أو konanc كمجمعين ، وهو أمر مربك إلى حد ما. لذا - إنه نفس الشيء. هنا هو الدليل:
تجميع
# $KOTLINC_HOME/kotlinc -opt ./hellokt.kt -o hellokt -produce dynamic
باستخدام
مفتاح التبديل -opt
، تكون المكتبة أصغر.
- إنتاج ديناميكي يخبر المترجم بعمل
مكتبة مشتركة للنظام الأساسي الحالي.
بعد التنفيذ ، سيكون لدينا ملفان: libhellokt.so و hellokt_api.h. مكتبة وملف رأس له. يرجى ملاحظة أنه يتم إنشاء البادئات واللاحقات تلقائيًا ولا يمكننا التأثير عليها (ربما).
في حالتنا ، نحصل على ملف رأس.
#ifndef KONAN_HELLOKT_H #define KONAN_HELLOKT_H #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus typedef bool hellokt_KBoolean; #else typedef _Bool hellokt_KBoolean; #endif typedef char hellokt_KByte; typedef unsigned short hellokt_KChar; typedef short hellokt_KShort; typedef int hellokt_KInt; typedef long long hellokt_KLong; typedef float hellokt_KFloat; typedef double hellokt_KDouble; typedef void* hellokt_KNativePtr; struct hellokt_KType; typedef struct hellokt_KType hellokt_KType; typedef struct { void (*DisposeStablePointer)(hellokt_KNativePtr ptr); void (*DisposeString)(const char* string); hellokt_KBoolean (*IsInstance)(hellokt_KNativePtr ref, const hellokt_KType* type); struct { struct { void (*kt_print)(const char* string); } root; } kotlin; } hellokt_ExportedSymbols; extern hellokt_ExportedSymbols* hellokt_symbols(void); #ifdef __cplusplus } #endif #endif
الوصول إلى وظيفة kt_print سيذهب بهذه الطريقة.
hellokt_symbols()->kotlin.root.kt_print(char *);
سأخبرك عن الفئات والحزم أدناه - هناك فروق دقيقة.المكتبة جاهزة ، اذهب إلى C
config.m4 (
كيفية إنشائه )
PHP_ARG_ENABLE(hello, whether to enable hello support,[ --enable-hello Enable hello support]) if test "$PHP_HELLO" != "no"; then PHP_ADD_LIBRARY_WITH_PATH(hellokt, /path/to/compiled/library, HELLO_SHARED_LIBADD) PHP_NEW_EXTENSION(hello, hello.c, $ext_shared) PHP_SUBST(HELLO_SHARED_LIBADD) fi
السطر الأول مطلوب!
أول شيء شوهد في المثال config.m4 أعلاه ، بخلاف بعض التعليقات ، هو ثلاثة أسطر تستخدم PHP_ARG_WITH () و PHP_ARG_ENABLE ().
...
يجب أن يوفر كل امتداد اسم الامتداد واحدًا أو آخر على الأقل ، بحيث يمكن للمستخدمين اختيار ما إذا كان سيتم إنشاء الامتداد في PHP أم لا.
لاحظ أنه في PHP_ADD_LIBRARY_WITH_PATH ، تكون الوسيطة الأولى هي اسم المكتبة. ليس libhellokt ، أي hellokt. قتلت ساعتين حتى اكتشفت لماذا لا يمكنني العثور على المكتبة. (هنا هو القصة الموعودة عن البلطجة الرابط).
الآن ، في الواقع ، رمز التمديد نفسه
مرحبا ج #include "php.h"
هناك عدد غير قليل من المقالات حول كتابة امتدادات PHP ، والوثائق موجودة ، لذلك سأقتصر على ارتباط
لاستخدام zend_parse_parameters - سيكون في مكانه.
حسنًا ، إذاً كل شيء على المسار المدلفن:
# $PHP_PATH/phpize # ./configure --with-php-config=$PHP_PATH/php-config # make # $PHP_PATH/php -dextension=./modules/hello.so -r "echo hello('World');" Hello, World!!!
مكافأة حول الطبقات والحزم
لنفترض أننا أردنا عمل فنغ شوي وإخفاء هذا الرمز.
package hello.kt; public class HelloKt { fun kt_print(string: String) { println("Hello, $string!!!") } }
لا توجد طريقة لإجراء استدعاء طريقة معتاد هنا - سيتعين عليك أولاً إنشاء فئة وتمريرها إلى أول وسيطة للدالة المطلوبة.
hellokt_kref_hello_kt_HelloKt helloKt = { 0 }; if(!helloKt.pinned){ helloKt = hellokt_symbols()->kotlin.root.hello.kt.HelloKt.HelloKt(); } hellokt_symbols()->kotlin.root.hello.kt.HelloKt.kt_print(helloKt, name);
ما هي الخطوة التالية؟ رفض المكتبة المشتركة ، والتقليل من استخدام C ، وما لا يمزح الجحيم ، والإطار المصغر هو شيء من هذا القبيل. أتمنى لي حظا سعيدا! :)