diff --git a/4.2/3.md b/4.2/3.md
index 3296bc3..4c97ef5 100644
--- a/4.2/3.md
+++ b/4.2/3.md
@@ -3,10 +3,45 @@ Plugins lesson 3.
| | |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Умеет формировать API для подключения плагинов.
Умеет создавать и собирать плагины в соответствии с заданным API.
(C)
Умеет подключать и отключать плагины в рантайме. (загрузка библиотеки и ее выгрузка) | На примере торговых ботов для биржи создадим систему с возможностью подключения плагинов. Научимся формировать API для плагинов, собирать и подключать их в рантайме, а также управлять ими — включать и отключать по мере необходимости.
Урок - практический. Студент после него сможет писать аналогичные решения, что мы и проверим в проекте.
Торговый бот - контекст, в котором показываются примеры (не production bot)
Придумать 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 {
+ Ok(Plugin {
+ plugin: unsafe { libloading::Library::new(filename) }?,
+ })
+ }
+ pub fn interface(&self) -> Result, 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>,
+}
+```
\ No newline at end of file