غیر ملکی فنکشن انٹرفیس (FFI)
انگریزی میں iroha_ffi خانہ سی پیدا کرنے کے لئے میکرو اور خصوصیات فراہم کرتا ہے ABI سے پابندیاں Rust APIs. اس کا استعمال جہاں Iroha اقسام کو ایک پار کرنے کی ضرورت ہے FFI حد، مثال کے طور پر SDK پابندیاں یا میزبان انضمام.
کیوں FFI
ایک فنکشن ایک غیر معمولی ادارہ ہے، اور اگرچہ زیادہ تر زبانیں اس بات پر متفق ہیں کہ فنکشن کو کیا کرنا چاہئے، جس طرح سے افعال کی نمائندگی کی جاتی ہے وہ بہت مختلف ہے. اس کے علاوہ ، کچھ زبانوں میں ، جیسے Rust ، کسی فنکشن کو کال کرنے کے نتائج اور وہ چیزیں جو اسے کرنے کی اجازت ہے وہ بھی مختلف ہیں۔ جب Rust APIs کو دوسری زبان یا مختلف میزبان ماحول سے کال کرنے کی ضرورت ہو تو ، Iroha کھیل کے میدان کو برابر کرنے کے لئے غیر ملکی فنکشن انٹرفیس (FFI) کا استعمال کرتا ہے.
آج استعمال ہونے والا بنیادی معیار سی ایپلی کیشنز بائنری انٹرفیس ہے۔ یہ آسان ، وسیع پیمانے پر دستیاب اور مستحکم ہے۔ اصولی طور پر ، آپ دستی طور پر سب کچھ کر سکتے ہیں ، لیکن Iroha موجودہ Rust API سے FFI کے مطابق افعال پیدا کرنے کے لئے iroha_ffi خانہ فراہم کرتا ہے۔
یقیناً آپ اپنی مرضی کے مطابق یہ کر سکتے ہیں۔ iroha_ffi خانہ صرف وہ کوڈ تیار کرتا ہے جسے آپ کو ویسے بھی پیدا کرنے کی ضرورت ہوگی۔ ضروری بوائلر پلیٹ لکھنے کے لئے کافی محتاط اور نظم و ضبط کی ضرورت ہوتی ہے۔ FFI کی حد سے زیادہ ہر فنکشن کال unsafe ہے جس میں غیر متعین رویے کا سبب بننے کا امکان ہے۔ جس طریقہ کے ذریعہ ہم اسے حل کرنے میں کامیاب ہوئے ، اس کے گرد گھومتا ہے robust repr(C) اقسام کا استعمال کرتے ہوئے.
INFO
صرف استثناء اشارے ہیں۔ باطل چیک اور درستگی کو عالمی سطح پر نافذ نہیں کیا جاسکتا ہے ، لہذا خام اشارے (ہمیشہ کی طرح) صرف غیر معمولی معاملات میں استعمال ہوتے ہیں۔ چونکہ ہم Iroha ڈیٹا ماڈل میں کسی اعتراض کے تقریبا ہر مثال کے ارد گرد لفافے فراہم کرتے ہیں، آپ کو خام اشارے کا استعمال کرنے کی ضرورت نہیں ہوگی.
مثال
یہاں ایک پابندی پیدا کرنے کی ایک مثال ہے:
#[derive(FfiType)]
struct DaysSinceEquinox(u32);
#[ffi_export]
impl DaysSinceEquinox {
pub fn update_value(&mut self, a: &u8) {
self.0 = *a as u32;
}
}مندرجہ بالا مثال DaysSinceEquinox کے ساتھ مندرجہ ذیل پابندیاں پیدا کرے گی جو ایک غیر شفاف اشارے کے طور پر نمائندگی کی جاتی ہے:
pub extern fn DaysSinceEquinox__update_value(handle: *mut DaysSinceEquinox, a: *const u8) -> FfiReturn {
// function implementation
}FFI پابند نسل
iroha_ffi خانہ افعال پیدا کرنے کے لئے استعمال کیا جاتا ہے جو FFI کے ذریعہ کال کیے جاسکتے ہیں۔ Rust اسٹریٹکس اور طریقوں کو دیکھتے ہوئے ، وہ unsafe کوڈ تیار کرتے ہیں جس کی آپ کو منسلک حدود سے عبور کرنے کے ل need ضرورت ہوگی۔
ایک Rust ٹائپ کو مضبوط میں تبدیل کیا جاتا ہے repr(C) ٹائپ جس میں پار کر سکتے ہیں FFI سرحد کے ساتھ FfiType::into_ffi. یہ بھی اس کے برعکس ہے: FFI ReprC ٹائپ کو ایک میں تبدیل کیا جاتا ہے Rust ٹائپ via FfiType::try_from_ffi.
WARNING
نوٹ کریں کہ مخالف تبادلہ غلط ہے اور غیر متعین رویے کا سبب بن سکتا ہے۔ اگرچہ ہم سب سے زیادہ واضح غلطیوں سے بچنے کی پوری کوشش کر سکتے ہیں ، آپ کو اپنے اختتام پر پروگرام کی درستگی کو یقینی بنانا چاہئے۔
بائنڈنگ جنریشن کی اجازت دینے والی اہم خصوصیات ReprC، FfiType، اور FfiConvert ہیں۔
| خصلت | تفصیل |
|---|---|
ReprC | یہ خصوصیت ایک مضبوط قسم کی نمائندگی کرتی ہے جو C ABI کے مطابق ہے۔ اس قسم کو FFI سرحدوں پر محفوظ طریقے سے تقسیم کیا جاسکتا ہے۔ |
FfiType | یہ خصوصیت ایک متعلقہ وضاحت کرتا ہے ReprC ایک مخصوص قسم کے لئے Rust قسم۔ بیان کردہ ReprC ٹائپ کی جگہ استعمال کیا جاتا ہے Rust ٹائپ میں API پیدا ہونے والی FFI فنکشن. |
FfiConvert | یہ خصوصیت دو طریقوں into_ffi اور try_from_ffi کی وضاحت کرتی ہے جو Rust قسم کو ReprC قسم سے یا اس سے تبدیل کرنے کے لئے استعمال ہوتے ہیں۔ |
نوٹ کریں کہ FFI پر کسی بھی ملکیت کی منتقلی نہیں ہے سوائے غیر شفاف اشارے کی اقسام کے۔ دیگر تمام اقسام جو ملکیت رکھتے ہیں ، جیسے Vec<T> ، کلونڈ ہیں۔
نام Mangling
FFI اشیاء کے پیدا کردہ ناموں میں دوہری underscores کا استعمال نوٹ کریں:
StructNameڈھانچے پر بیان کردہinherent_fnطریقہ کار کے لئے، FFI کا نامStructName__inherent_fnہوگا.StructNameڈھانچے میںTraitNameصفات سےMethodNameطریقہ کار کے لئے، FFI کا نامStructNameTraitNameMethodNameہوگا.StructNameڈھانچے میںfield_nameفیلڈ مقرر کرنے کے لئے، FFI فنکشن کا نامStructName__set_field_nameہوگا.StructNameڈھانچے میںfield_nameفیلڈ حاصل کرنے کے لئے، FFI فنکشن کا نامStructName__field_nameہوگا.StructNamestructure میں mutablefield_nameفیلڈ حاصل کرنے کے لئے، FFI فنکشن کا نامStrucuName__field_name_mutہوگا.آزاد
module_name::fn_nameکے لئے، FFI کا نامmodule_name::__fn_nameہوگا.ان خصوصیات کے لئے جو عام نہیں ہیں اور FFI میں ان کی تنصیب کا اشتراک کرنے کی اجازت دیتے ہیں (نیچے
Cloneدیکھیں) ، FFI کا نامmodule_name::__cloneہوگا۔rustimpl Clone for Type1 { fn clone(&self) -> Self; } impl Clone for Type2 { fn clone(&self) -> Self; }