موضوع مقاله: واسطه تابع خارجی | مخاطب: عمومی | لحن: دانشنامه‌ای | ساختار: عنوان، مقدمه، 3 بخش، جمع‌بندی | مقاله: | # واسطه تابع خارجی | مقدمه: واسطه توابع خارجی (FFI) مکانیزمی است که به برنامه‌ای نوشته‌شده در یک زبان برنامه‌نویسی این امکان را می‌دهد که از روتین‌ها یا خدماتی که در زبان یا محیط دیگر نوشته یا کامپایل شده‌اند، استفاده کند یا آن‌ها را فراخوانی کند. | ## بخش 1: واسطه تابع خارجی | FFI معمولاً در مواقعی استفاده می‌شود که فراخوانی‌ها به یک کتابخانه پیوند داینامیک باینری (DLL) انجام می‌شود. نامگذاری اصطلاح "واسطه توابع خارجی" (FFI) از مشخصات زبان برنامه‌نویسی Common Lisp می‌آید که به‌طور صریح به ویژگی زبان برنامه‌نویسی اشاره دارد که امکان فراخوانی‌های بین زبان‌ها را فراهم می‌کند. عملکرد وظیفه اصلی یک واسط توابع خارجی (FFI) تطبیق معنای دستورها و قراردادهای فراخوانی یک زبان برنامه‌نویسی (زبان میزبان، یا زبانی که FFI را تعریف می‌کند) با معنای دستورها و قراردادهای زبان دیگری (زبان مهمان) است. این فرایند باید محیط‌های اجرایی و رابط‌های باینری برنامه‌های هر دو زبان را نیز مد نظر قرار دهد. این کار می‌تواند به چندین روش انجام شود: نیاز به این که توابع زبان مهمان که قرار است به زبان میزبان قابل فراخوانی باشند به روشی خاص مشخص یا پیاده‌سازی شوند، که اغلب از نوعی کتابخانه سازگاری استفاده می‌کنند. استفاده از ابزاری برای بسته‌بندی خودکار توابع به زبان مهمان با کد چسب مناسب، که هر گونه ترجمه لازم را انجام می‌دهد. استفاده از کتابخانه لفاف دار محدود کردن مجموعه ای از توانایی‌های زبان میزبان که می‌تواند بین زبانی استفاده شود. به عنوان مثال، توابع C++ که از C فراخوانی می‌شوند ممکن است (به‌طور کلی) شامل پارامترهای مرجع یا استثناهای پرتابی نباشند. Iها ممکن است با ملاحظات زیر پیچیده شوند: اگر یک زبان از جمع‌آوری زباله (GC) پشتیبانی می‌کند و زبان دیگر از جمع‌آوری زباله پشتیبانی نمی‌کند. | ## بخش 2: واسطه تابع خارجی | برای مثال، در JNI، کد C که ارجاعات شی را که از جاوا دریافت می‌کند نگه می‌دارد، باید این اطلاعات را با موفقیت به ماشین مجازی جاوا یا محیط زمان اجرا جاوا (JRE) منتقل کند، در غیر این صورت، جاوا ممکن است اشیاء را قبل از اینکه C با آنها تمام شود حذف کند. (کد C همچنین باید به صراحت پیوند خود را به هر یک از این شیء آزاد کند، زمانی که C دیگر نیازی به آن شیء نداشته باشد) ممکن است نگاشت اشیاء یا نوع داده‌های پیچیده یا غیر پیش پا افتاده از یک محیط به محیط دیگر دشوار باشد. به دلیل مشکل نگاشت فوق، ممکن است برای هر دو زبان امکان حفظ ارجاعات به یک نمونه از یک شیء قابل تغییر وجود نداشته باشد. علاوه بر این، اگر هر دو وجود داشته باشند، اینها اغلب ماشین‌های مجازی متفاوتی هستند. وراثت بین زبانی و تفاوت‌های دیگر، مانند بین سیستم‌های نوع یا بین مدل‌های ترکیب شی، ممکن است به‌ویژه دشوار باشد. زبان Ada دارای پیوندهایی است که اجازه می‌دهد نه‌تنها توابع خارجی را فراخوانی کند، بلکه توابع و متدهای خودش را هم طوری صادر کند که از زبان‌های غیر Ada قابل فراخوانی باشند. زبان ++C یک رابط ساده با زبان C دارد، چون بخش بزرگی از دستور زبان آن‌ها مشترک است. با این حال، در مورد زبان‌های افزونه، ممکن است معکوس شدن معنایی رابطه مهمان و میزبان رخ دهد، جایی که یک زبان افزونه کوچک به عنوان مهمان خدماتی را در یک زبان میزبان بزرگتر فراخوانی می‌کند. برخی از FFIها فقط به توابع ایستاده محدود هستند، در حالی که برخی دیگر اجازه می‌دهند توابعی که در یک شی یا کلاس جاسازی شده‌اند، فراخوانی شوند. | ## بخش 3: واسطه تابع خارجی | در بیشتر موارد، یک FFI توسط یک زبان سطح بالاتر تعریف می‌شود تا از خدماتی که در یک زبان سطح پایین‌تر مانند C یا C++ تعریف و پیاده‌سازی شده‌اند، استفاده کند. بسیاری از FFIها همچنین به زبان فراخوانی شده این امکان را می‌دهند که خدماتی را در زبان میزبان فراخوانی کند. اصطلاح رابط تابع خارجی معمولاً برای توصیف زمان‌بندی‌های چندزبانه مانند زمان‌بندی مشترک زبان (CLR) مایکروسافت استفاده نمی‌شود، جایی که یک بستر مشترک فراهم می‌شود که به هر زبان CLR سازگار اجازه می‌دهد از خدماتی که در هر زبان دیگری تعریف شده استفاده کند. با این حال، در مورد زبان‌های توسعه، ممکن است یک وارونگی معنایی در رابطه مهمان و میزبان رخ دهد، زمانی که بخش کوچکتری از زبان توسعه، به عنوان مهمان، سرویس‌هایی را از زبان میزبان بزرگتر فراخوانی می‌کند، مانند نوشتن یک پلاگین کوچک برای GIMP. برخی از FFIها محدود به توابع مستقل هستند، در حالی که برخی دیگر اجازه می‌دهند که توابع تعبیه شده در یک شیء یا کلاس (که معمولاً به آن فراخوانی متد گفته می‌شود) نیز فراخوانی شوند؛ برخی حتی اجازه می‌دهند که داده‌های پیچیده یا اشیاء از مرز زبان عبور کنند. در بیشتر موارد، FFI توسط یک زبان سطح بالاتر تعریف می‌شود تا از خدمات تعریف‌شده و پیاده‌سازی‌شده در یک زبان سطح پایین‌تر استفاده کند، معمولاً زبان‌های برنامه‌نویسی سیستم مانند C یا C++. این کار معمولاً برای دسترسی به خدمات سیستم‌عامل (OS) در زبان‌هایی که API سیستم‌عامل در آن تعریف شده یا برای اهداف بهینه‌سازی عملکرد انجام می‌شود. | ## جمع‌بندی | از آنجا که هیچ رابطی وجود ندارد، به‌طور دقیق‌تر نمی‌توان آن‌ها را FFI در نظر گرفت، در حالی که همان عملکردها را برای کاربر ارائه می‌دهند.