Гадаад үйл ажиллагааны интерфейс (FFI)
Үндсэн хуулийн iroha_ffi C үйлдвэрлэлийн макро болон шинж чанарууд нь C ABI Нүүр хуудас Rust APIs. Энэ нь Iroha төрлүүд нь дамжин FFI хязгаар, жишээ нь: SDK холболт эсвэл халамжийн нэгтгэл.
Яагаад FFI
Хөдөлмөр нь харьцангуй ухамсарсан нэгж бөгөөд ихэнх хэл функцын юу хийх ёстой талаар санал нэг байдаг ч, Хөдөлмөрийг илэрхийлэх арга нь маш ялгаатай байдаг. Rust, функцыг дуудах үр дагавар, түүний хийх зөвшөөрөлтэй зүйлүүд ч ялгаатай байдаг. Rust APIs өөр хэлээс эсвэл бусад хүлээн авч буй орчныгсаа дуудлага авах шаардлагатай. Iroha гадаад функцын интерфейс ашигладаг (FFI) өрсөлдөх нөхцөлийг тэгш болгох.
Өнөөдрийн хэрэглэгддэг үндсэн стандарт нь C аппликацын бинар интерфейс юм. Энэ нь энгийн, өргөн хүрээнд хүртээмжтэй, тогтвортой юм. Принципийн хувьд та бүх зүйлийг гараар хийж болно, гэхдээ Iroha бол FFI-ийн нийцсэн функцыг бий байгаа Rust API -ээс үүсгэх iroha_ffi хайрцаг бүрдүүлжээ.
Мэдээжийн хэрэг, та өөрийн гэсэн аргаар хийж болно. iroha_ffi crate нь зүгээр л та ямар ч тохиолдолд үүсгэх хэрэгтэй код бий болгодог. Шаардлагатай бөмбөрцгийг бичихийн тулд маш их хичээл зүтгэл, сахилга шаарддаг. FFI хязгаар нь unsafe тодорхойгүй заншил үүсгэх боломжтой. Энэ асуудлыг шийдэх арга зам нь repr(C) Ард түмэн.
INFO
Зөвхөн нөөц үзүүлэгчид л ялгаатай. null шалгалт болон хүчин төгөлдөр байдлыг дэлхий даяар хэрэгжүүлэх боломжгүй тул түүхий эд нөөцийг (хүнтэй болгон) зөвхөн онцгой тохиолдолд ашигладаг байна. 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 код бий болгоно.
Rust хэлбэрийг repr(C) хэлбэрээр өөрчилж, FFI хязгаарыг FfiType::into_ffi -тэй давтаж болно. Энэ нь эсрэгээрээ ч явагддаг: FFI ReprC хэлбэрийг Rust хэлбэрээр FfiType::try_from_ffi дамжуулан өөрчлөх боломжтой.
WARNING
Харин эсрэг хэлбэр нь алдаатай бөгөөд тодорхойгүй зан үйл үүсгэх боломжтой гэдгийг анхаараарай. Бид хамгийн ил тод алдаанаас зайлсхийхийн тулд чадах бүхнээ хийж чаддаг хэдий ч та програмын зөв байдлыг хангах ёстой.
Төгсэл үүсгэх боломжийг олгодог үндсэн шинж чанар нь ReprC, FfiType, FfiConvert.
| Үргэлж . | Тодруулга |
|---|---|
ReprC | Энэ шинж чанар нь C ABI -д нийцсэн хүчтэй хэлбэр юм. Тус хэлбэрийг FFI -ийн хилүүдэд аюулгүй хуваалцах боломжтой. |
FfiType | Энэ шинж чанар нь тухайн Rust төрөлд хамааралтай ReprC хэлбэрийг тодорхойлдог. үүссэн FFI функцын API функцинд Rust хэлбэрийн оронд тодорхойлсон ReprC хэлбэр ашиглагддаг. |
FfiConvert | Энэ шинж чанар нь хоёр арга барилыг тодорхойлдог. into_ffi болон try_from_ffi Хөдөлмөрийн эргэлт хийхэд ашигладаг Rust тоног төхөөрөмж ReprC Үндэсний төрөл. |
FFI-ийн өмчлөх хөрөнгийн шилжилт байхгүй гэдгийг анхаарна уу, зөвхөн ил тод үзүүлэлтийн төрөлүүдээс бусад нь Vec<T> гэх мэт өмчлөлтэй бүхий бусад төрөлүүдийг клонируулсан байна.
Нэр Манглинг
FFI тоног төхөөрөмжийн бүтээгдсэн нэрүүдэд хоёр давхар дэглэмийн хэрэглээг анхаарна уу:
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бүтэц дэх өөрчлөгдөж болохfield_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; }