Экспорт функций
Руководство по экспорту функций из вашего плагина на Rust для использования другими языковыми модулями в Plugify.
В экосистеме Plugify плагины на Rust могут экспортировать функции, делая их доступными для других плагинов. Это руководство объясняет, как экспортировать функции в Rust, и содержит примеры, которые помогут вам бесшовно интегрировать ваши плагины.
Базовое сопоставление типов
В следующей таблице показано, как типы предоставляются в API Rust:
| Тип C++ | Тип Rust | Псевдоним Plugify | Поддержка ref? |
|---|---|---|---|
| void | () | void | ❌ |
| bool | bool | bool | ✅ |
| char | i8 | char8 | ✅ |
| char16_t | u16 | char16 | ✅ |
| int8_t | i8 | int8 | ✅ |
| int16_t | i16 | int16 | ✅ |
| int32_t | i32 | int32 | ✅ |
| int64_t | i64 | int64 | ✅ |
| uint8_t | u8 | uint8 | ✅ |
| uint16_t | u16 | uint16 | ✅ |
| uint32_t | u32 | uint32 | ✅ |
| uint64_t | u64 | uint64 | ✅ |
| uintptr_t | usize | ptr64 | ✅ |
| uintptr_t | usize | ptr32 | ✅ |
| float | f32 | float | ✅ |
| double | f64 | double | ✅ |
| void* | *const c_void | function | ❌ |
| plg::string | Str | string | ✅ |
| plg::any | Any | any | ✅ |
| plg::vector<bool> | Arr<bool> | bool[] | ✅ |
| plg::vector<char> | Arr<i8> | char8[] | ✅ |
| plg::vector<char16_t> | Arr<u16> | char16[] | ✅ |
| plg::vector<int8_t> | Arr<i8> | int8[] | ✅ |
| plg::vector<int16_t> | Arr<i16> | int16[] | ✅ |
| plg::vector<int32_t> | Arr<i32> | int32[] | ✅ |
| plg::vector<int64_t> | Arr<i64> | int64[] | ✅ |
| plg::vector<uint8_t> | Arr<u8> | uint8[] | ✅ |
| plg::vector<uint16_t> | Arr<u16> | uint16[] | ✅ |
| plg::vector<uint32_t> | Arr<u32> | uint32[] | ✅ |
| plg::vector<uint64_t> | Arr<u64> | uint64[] | ✅ |
| plg::vector<uintptr_t> | Arr<usize> | ptr64[] | ✅ |
| plg::vector<uintptr_t> | Arr<usize> | ptr32[] | ✅ |
| plg::vector<float> | Arr<f32> | float[] | ✅ |
| plg::vector<double> | Arr<f64> | double[] | ✅ |
| plg::vector<plg::string> | Arr<Str> | string[] | ✅ |
| plg::vector<plg::any> | Arr<Any> | any[] | ✅ |
| plg::vector<plg::vec2> | Arr<Vec2> | vec2[] | ✅ |
| plg::vector<plg::vec3> | Arr<Vec3> | vec3[] | ✅ |
| plg::vector<plg::vec4> | Arr<Vec4> | vec4[] | ✅ |
| plg::vector<plg::mat4x4> | Arr<Mat4x4> | mat4x4[] | ✅ |
| plg::vec2 | Vec2 | vec2 | ✅ |
| plg::vec3 | Vec3 | vec3 | ✅ |
| plg::vec4 | Vec4 | vec4 | ✅ |
| plg::mat4x4 | Mat4x4 | mat4x4 | ✅ |
Экспорт функций в Rust
Чтобы экспортировать функцию в плагине на Rust, необходимо убедиться, что она видима для других плагинов. Это делается с помощью атрибута #[unsafe(no_mangle)], предоставляемого крейтом Plugify.
Ключевые моменты
- No-mangle: макрос автоматически применяет
#[no_mangle], чтобы предотвратить искажение имён. - Extern "C": функции экспортируются с C-компоновкой для межъязыковой совместимости.
- Типы параметров и возвращаемых значений: используйте нативные типы Plugify для бесшовной интеграции.
Базовый пример
Вот простой пример экспорта функции в плагине на Rust:
Определение функции
Атрибут #[unsafe(no_mangle)] автоматически обеспечивает:
- Экспорт функции с C-компоновкой
- Предотвращение искажения имён
- Видимость функции для других плагинов
Пример манифеста плагина
Все экспортируемые функции должны быть описаны в файле манифеста плагина в разделе methods. Вот пример манифеста для плагина, экспортирующего функцию add_numbers:
Продвинутый пример: экспорт сложных функций
Вот пример экспорта функции со сложными типами параметров и возвращаемого значения:
Определение функции
Манифест плагина
Экспорт функций со ссылками
Rust позволяет экспортировать функции, принимающие изменяемые ссылки:
Определение функции
Манифест плагина
Обработка обратных вызовов
Plugify позволяет экспортировать функции, принимающие обратные вызовы в качестве параметров:
Определение функции
Манифест плагина
Работа с перечислениями
Перечисления Rust можно экспортировать в Plugify:
Определение перечисления
Манифест плагина с перечислением
Важно: перечисления, используемые в экспортируемых функциях, должны иметь #[repr(u8)], #[repr(i32)] или аналогичный атрибут для обеспечения совместимости ABI.
Рекомендации
- Используйте unsafe вместе с extern "C": всегда применяйте макрос
#[unsafe(no_mangle)]для экспорта функций. - Следуйте соглашениям о типах: используйте нативные типы Plugify для параметров и возвращаемых значений.
- Документируйте свои функции: используйте doc-комментарии Rust (
///) для документирования экспортируемых функций. - Поддерживайте манифест в актуальном состоянии: убедитесь, что манифест точно отражает ваши экспортируемые функции.
- Используйте repr для перечислений: всегда указывайте
#[repr(...)]для перечислений, используемых в экспортируемых функциях. - Тщательно тестируйте: проверяйте, что экспортируемые функции работают так, как ожидается, при вызове из других плагинов.
- Корректно обрабатывайте ошибки: рассмотрите использование типов
Result<T, E>и соответствующее преобразование ошибок.
Обработка ошибок
При экспорте функций, которые могут завершиться неудачей, рассмотрите следующий подход:
Заключение
Экспорт функций в плагинах на Rust выполняется просто, если следовать соглашениям и рекомендациям Plugify. Используя атрибут #[unsafe(no_mangle)], придерживаясь соглашений о типах и поддерживая актуальность файлов манифеста, вы сможете создавать надёжные и совместимые плагины. Типобезопасность и система владения Rust дают дополнительные гарантии, помогающие предотвратить распространённые ошибки при разработке плагинов.