vault backup: 2025-11-27 01:34:37
This commit is contained in:
parent
800ff994ba
commit
ab973b28c7
45
4.2/3.md
45
4.2/3.md
@ -3,10 +3,45 @@ Plugins lesson 3.
|
||||
| | |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Умеет формировать API для подключения плагинов. <br> <br>Умеет создавать и собирать плагины в соответствии с заданным API. <br>(C) <br> <br>Умеет подключать и отключать плагины в рантайме. (загрузка библиотеки и ее выгрузка) | На примере торговых ботов для биржи создадим систему с возможностью подключения плагинов. Научимся формировать API для плагинов, собирать и подключать их в рантайме, а также управлять ими — включать и отключать по мере необходимости. <br> <br>Урок - практический. Студент после него сможет писать аналогичные решения, что мы и проверим в проекте. <br> <br>Торговый бот - контекст, в котором показываются примеры (не production bot) <br> <br>Придумать API |
|
||||
В прошлых уроках мы изучили, что такое динамически подгружаемый код и как линковаться с ним, в этом уроке изучим способ более удобного взаимодействия с динамическими библиотеками
|
||||
|
||||
## Система плагинов
|
||||
В прошлом уроке мы узнали, что используя dlopen и dlsym можно динамически подгружать функции из отдельных файлов динамических библиотек. Это бывает полезно для уменьшения размера программы на диске и в оперативной памяти, а также выноса зависимостей в рациональные.
|
||||
## Start
|
||||
В прошлых уроках мы узнали, что используя dlopen и dlsym можно динамически подгружать функции из отдельных файлов динамических библиотек. Это бывает полезно для уменьшения размера программы на диске и в оперативной памяти, а также выноса зависимостей в рациональные.
|
||||
В этом уроке мы изучим взаимодействие с динамическими кодом более высокоуровневым способом: системой плагинов.
|
||||
## Система плагинов
|
||||
Система плагинов представляет собой подгружаемый функционал, взаимодействие с которым возможно через заранее определенный интерфейс. Как концепцию плагины можно представить так: прописывание трейта - определение интерфейса, а реализация трейта - уже сами плагины, но не вшитые в саму программу, а находящиеся в отдельном файле.
|
||||
Система плагинов представляет собой подгружаемый функционал, взаимодействие с которым возможно через заранее определенный интерфейс. Как концепцию плагины можно представить так: определение интерфейса это прописывание трейта, а реализация трейта - уже сами плагины, но не вшитые в саму программу, а находящиеся в отдельном файле.
|
||||
Давайте попробуем сделать систему плагинов для собственного торгового бота. Пускай интерфейсом будет одна функция trade, которая по переданому срезу u32 цен будет принимать решение: купить, продать или ничего не делать:
|
||||
```rust
|
||||
pub enum TradeAction {
|
||||
Sell(u32),
|
||||
Buy(u32),
|
||||
None,
|
||||
}
|
||||
|
||||
pub struct PluginInterface {
|
||||
pub trade: extern "Rust" fn(prices: &[u32]) -> TradeAction,
|
||||
}
|
||||
```
|
||||
Основная программа, после подгрузки плагина сможет по такому интерфейсу сможет воспользоваться плагином. Теперь, библиотеку с таким интерфейсом нужно как-нибудь подгружать. Это можно сделать используя dlopen и dlsym, но в данном примере для удобства воспользуемся библиотекой libloading.
|
||||
```rust
|
||||
pub struct Plugin {
|
||||
plugin: Library,
|
||||
}
|
||||
|
||||
impl Plugin {
|
||||
pub fn new(filename: &str) -> Result<Self, libloading::Error> {
|
||||
Ok(Plugin {
|
||||
plugin: unsafe { libloading::Library::new(filename) }?,
|
||||
})
|
||||
}
|
||||
pub fn interface(&self) -> Result<PluginInterface<'_>, libloading::Error> {
|
||||
Ok(PluginInterface {
|
||||
trade: unsafe { self.plugin.get("trade") }?,
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
Тут придется немного изменить интерфейс плагина, так как libloading добавляет лайфтаймы к функциям:
|
||||
```rust
|
||||
pub struct PluginInterface<'a> {
|
||||
pub trade: Symbol<'a, extern "Rust" fn(prices: &[u32]) -> TradeAction>,
|
||||
}
|
||||
```
|
||||
Loading…
x
Reference in New Issue
Block a user