Skip to content

غیر ملکی فنکشن انٹرفیس (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 ڈیٹا ماڈل میں کسی اعتراض کے تقریبا ہر مثال کے ارد گرد لفافے فراہم کرتے ہیں، آپ کو خام اشارے کا استعمال کرنے کی ضرورت نہیں ہوگی.

مثال

یہاں ایک پابندی پیدا کرنے کی ایک مثال ہے:

rust
#[derive(FfiType)]
struct DaysSinceEquinox(u32);

#[ffi_export]
impl DaysSinceEquinox {
    pub fn update_value(&mut self, a: &u8) {
        self.0 = *a as u32;
    }
}

مندرجہ بالا مثال DaysSinceEquinox کے ساتھ مندرجہ ذیل پابندیاں پیدا کرے گی جو ایک غیر شفاف اشارے کے طور پر نمائندگی کی جاتی ہے:

rust
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 ہوگا.

  • StructName structure میں mutable field_name فیلڈ حاصل کرنے کے لئے، FFI فنکشن کا نام StrucuName__field_name_mut ہوگا.

  • آزاد module_name::fn_name کے لئے، FFI کا نام module_name::__fn_name ہوگا.

  • ان خصوصیات کے لئے جو عام نہیں ہیں اور FFI میں ان کی تنصیب کا اشتراک کرنے کی اجازت دیتے ہیں (نیچے Clone دیکھیں) ، FFI کا نام module_name::__clone ہوگا۔

    rust
    impl Clone for Type1 {
        fn clone(&self) -> Self;
    }
    impl Clone for Type2 {
        fn clone(&self) -> Self;
    }