Взаимодействие с C++
В сообществе Rust есть несколько вариантов взаимодействия C++ и Rust, и новые инструменты постоянно разрабатываются. Сейчас Chromium использует инструмент под названием CXX.
Вы описываете всю границу между языками на языке описания интерфейсов (который очень похож на Rust), а затем инструменты CXX генерируют объявления функций и типов как в Rust, так и в C++.
Полный пример использования смотрите в руководстве по CXX.
Пройдитесь по диаграмме. Объясните, что за кулисами делается ровно то же, что вы делали раньше вручную. Укажите, что автоматизация процесса даёт следующие преимущества:
- Инструмент гарантирует согласованность сторон C++ и Rust (например, вы получите ошибки компиляции, если
#[cxx::bridge]не соответствует реальным определениям на C++ или Rust, тогда как при рассинхронизированных ручных привязках возникло бы неопределённое поведение) - Инструмент автоматизирует генерацию 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 из входных данных, не являющихся UTF-8, аrust::String::c_strможет завершить строку NUL-символом).