Взаємодія з C++
Спільнота Rust пропонує кілька варіантів взаємодії C++/Rust, при цьому постійно розробляються нові інструменти. Наразі у Chromium використовується інструмент під назвою CXX.
Ви описуєте всю вашу мовну границю мовою визначення інтерфейсів (яка дуже схожа на Rust), а потім інструменти CXX генерують оголошення для функцій і типів як на Rust, так і на C++.
Перегляньте підручник з CXX, щоб отримати повний приклад використання цього.
Поговоріть про схему. Поясніть, що за лаштунками відбувається те саме, що ви робили раніше. Зазначте, що автоматизація процесу має такі переваги:
- Інструмент гарантує, що сторони C++ та Rust збігаються (наприклад, ви отримаєте помилки компіляції, якщо
#[cxx::bridge]
не збігається з фактичними визначеннями C++ або Rust, а з несинхронізованими ручними прив'язками ви отримаєте Undefined Behavior). - Інструмент автоматизує генерацію заглушок FFI (невеликих, C-ABI-сумісних, вільних функцій) для не-C функціоналу (наприклад, увімкнення викликів FFI в методи Rust або C++; ручне прив'язування вимагало б написання таких вільних функцій верхнього рівня вручну).
- Інструмент і бібліотека можуть працювати з набором основних типів, наприклад:
&[T]
можна передавати через межу FFI, навіть якщо це не гарантує певного ABI або розміщення пам'яті. При ручному зв'язуванніstd::span<T>
/&[T]
потрібно вручну деструктурувати і відновити з вказівника і довжини - це може призвести до помилок, оскільки кожна мова представляє порожні зрізи дещо по-різному- Розумні вказівники типу
std::unique_ptr<T>
,std::shared_ptr<T>
та/абоBox
підтримуються за замовчуванням. При ручному прив'язуванні потрібно було б передавати C-ABI-сумісні необроблені вказівники, що збільшило б ризики для тривалості життя та безпеки пам'яті. - Типи
rust::String
іCxxString
розуміють і підтримують відмінності у представленні рядків у різних мовах (наприклад,rust::String::lossy
може створити рядок Rust із вхідних даних не у форматі UTF8, аrust::String::c_str
може завершити рядок NUL).