سؤال

الآن أنا أعمل على لغة نصية لا تملك حتى الآن FFI. أود أن أعرف ما هي الطريقة الأكثر ملاءمة للحصول عليها، على افتراض أنني أود أن أكتبها مثل المهوسين البارد - أود أن أكتب FFI في لغة البرمجة النصية نفسها.

لغة البرمجة التي أحتاج إلى واجهة هي C. لذلك بالنسبة للأساسيات التي أعرفها أن libdl.so هو أفضل صديق لي. من الواضح أنه ليس الشيء الوحيد الذي سأحتاج إليه ولكن أهمها.

ليس لدي أفكار طفيفة فقط حول ماذا أحتاج إليها. أرغب في الحصول على سلوك مماثل من FFI كما له ما لديه Python Ctypes.

ما الذي يجب علي أن أعرفه من أجل الحصول على هذا بعيدا؟ أعلم أن هناك بعض السحر الخطير مع هياكل البيانات سأحتاج إلى التعامل معها. كيف يمكنني إدارتها حتى أتمكن من فعل معظم هذا السحر الخطير في لغة البرمجة النصية نفسها؟ كنت أستخدم من هذا السحر لأكثر من ذلك بكثير من واجهة الوظائف الأجنبية فقط. على سبيل المثال، قد أرغب في نقل البيانات الثنائية مثل C إلى الملفات.

هل كانت مفيدة؟

المحلول

أعتقد أن إجابة التباين تتطلب مقال مفصل.

في الأساس، يجب أن يكون هناك مغلفة لاستعراض تحميل ومكتبة مرافق البحث الرمز المقدم من نظام التشغيل المضيف. إذا تم تمثيل بيانات البيانات الأساسية لغتك داخليا بنية بيانات واحدة واحدة، فيمكن وضع متطلبات على مطوري المكتبة التي يجب أن تكون المعلمات ونوع الإرجاع من وظائف C تصديرها كائنات من بنية البيانات. سيؤدي ذلك إلى جعل تبادل البيانات أبسط لتنفيذ. إذا كانت لغتك تحتوي على شكل من أشكال التعبيرات النمطية ووظائف الطبقة الأولى، فقد تتم كتابة توقيع وظائف C في أنماط وتفتيش المكتبة للحصول على وظيفة مطابقة للتوقيع المكافئ. فيما يلي بعض pseudocode من وظيفة C واستخدامها في البرنامج النصي:

/* arith.dll */
/* A sample C function callable from the scripting language. */

#include "my_script.h" // Data structures used by the script interpreter.

My_Script_Object* add(My_Script_Object* num1, My_Script_Object* num2)
{
   int a = My_Script_Object_To_Int(num1);
   int b = My_Script_Object_To_Int(num2);
   return Int_To_My_Script_Object(a + b);
}

/* End of arith.dll */

// Script using the dll
clib = open_library("arith.dll");

// if it has first-class functions
add_func = clib.find([add int int]);
if (cfunc != null)
{
   sum = add_func(10, 20);
   print(sum);
}

// otherwise
print(clib.call("add", 10 20));

لا يمكن مناقشة المزيد من تفاصيل التنفيذ هنا. لاحظ أننا لم نقول أي شيء عن جمع القمامة، إلخ.

قد تساعدك المصادر المتوفرة على الروابط التالية في النقل

http://common-lisp.net/project/cffi/ http://www.nongnu.org/cinvoke/

نصائح أخرى

الدفع http://sourceware.org/libffi/

تذكر أن اتفاقيات الدعوة ستكون مختلفة عن بنية مختلفة، أي ما يتم برزتها متغيرات وظيفة النظام على المكدس. لا أعرف عن كتابةها في لغة البرمجة النصية الخاصة بك، أعرف أن Java Jni يستخدم Libffi.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top