Сит функциялар интерфейстары (FFI)
Ҡоролтай iroha_ffi коробка C сығарыу өсөн макролар һәм һыҙаттар бирә ABI бәйләнештәр Rust APIs. Унда ҡулланыла: Iroha Типтар аша сығырға кәрәк FFI сиктәре, мәҫәлән: SDK бәйләнештәр йәки ҡабул итеүсе интеграциялар.
Ни өсөн FFI
Функция абстракт берәмек булып тора, һәм күпселек телдәр функцияның нимә эшләргә тейешлеге менән килешһә лә, Функцияларҙың сағылыш алымы бик төрлө. Rust, Функцияны саҡырыуҙың эҙемтәләре һәм уға эшләргә рөхсәт ителгән нәмәләр ҙә төрлө. Rust APIs икенсе телдән йәки башҡа ҡабул итеү мөхитенән шылтыратырға кәрәк, Iroha сит функциялар интерфейсын ҡуллана (FFI) уйындарҙы тигеҙләү өсөн.
Хәҙерге ваҡытта ҡулланылған төп стандарт - C ҡушымтаһы бинар интерфейсы. Ул ябай, киң таралған һәм тотороҡло. Принцип буйынса, һеҙ барыһын да ҡул менән эшләй алаһығыҙ, әммә Iroha тәьмин итә iroha_ffi яһау өсөн һандыҡ FFI- ғәмәлдә булған функциялар буйынса Rust API.
Һеҙ, әлбиттә, быны үҙ юлығыҙ менән эшләй алаһығыҙ. iroha_ffi һандығы бары тик кодты ғына тыуҙыра, уны һеҙ барыбер булдырырға тейеш инегеҙ. кәрәкле ҡаҙан пластинаһын яҙыу тырышлыҡ һәм дисциплина талап итә. FFI сигендәге һәр функция саҡырыуы unsafe булып тора, ул билдәһеҙ тәртип тыуҙырырға мөмкин. Беҙ уны хәл итеүгә өлгәшкән ысул ныҡлы 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 кодын булдыра.
А Rust тип ныҡлы әйләндерелә repr(C) тип аша сығырға мөмкин FFI сиктәре менән FfiType::into_ffi. Был шулай уҡ кире яҡҡа бара: FFI ReprC типҡа әйләндерелә Rust тип аша 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>, клонлаштырылған.
Исеме Манглинг
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; }