From ab973b28c7c416e76774ba8615c880c347255195 Mon Sep 17 00:00:00 2001 From: Akulij Date: Thu, 27 Nov 2025 01:34:37 +0700 Subject: [PATCH] vault backup: 2025-11-27 01:34:37 --- 4.2/3.md | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) 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