Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Взаимодействие с C++

В сообществе Rust есть несколько вариантов взаимодействия C++ и Rust, и новые инструменты постоянно разрабатываются. Сейчас Chromium использует инструмент под названием CXX.

Вы описываете всю границу между языками на языке описания интерфейсов (который очень похож на Rust), а затем инструменты CXX генерируют объявления функций и типов как в Rust, так и в C++.

Overview diagram of cxx, showing that the same interface definition is used to create both C++ and Rust side code which then communicate via a lowest common denominator C API

Полный пример использования смотрите в руководстве по 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-символом).