Interoperabilidade com C++

A comunidade Rust oferece várias opções para interoperabilidade C++/Rust, com novas ferramentas sendo desenvolvidas o tempo todo. No momento, o Chromium usa uma ferramenta chamada CXX.

Você descreve toda a fronteira da linguagem em uma linguagem de definição de interface (que se parece muito com Rust) e, em seguida, as ferramentas CXX geram declarações para funções e tipos em Rust e 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

Veja o tutorial CXX para um exemplo completo de como usá-lo.

Fale com o auxílio do diagrama. Explique que, nos bastidores, isso está fazendo exatamente o mesmo que você fez anteriormente. Aponte que automatizar o processo tem os seguintes benefícios:

  • A ferramenta garante que os lados C++ e Rust correspondam (por exemplo, você obterá erros de compilação se o #[cxx::bridge] não corresponder às definições C++ ou Rust reais, mas com bindings manuais fora de sincronia, você obteria Comportamento Indefinido)
  • A ferramenta automatiza a geração de thunks FFI (pequenas funções livres compatíveis com C-ABI) para recursos não-C (por exemplo, permitindo chamadas FFI para métodos Rust ou C++; bindings manuais exigiriam a autoria de tais funções livres de alto nível manualmente)
  • A ferramenta e a biblioteca podem lidar com um conjunto de tipos principais - por exemplo:
    • &[T] pode ser passado pela fronteira FFI, embora não garanta nenhum layout de memória ou ABI específico. Com bindings manuais, std::span<T> / &[T] devem ser manualmente destruturados e reconstruídos a partir de um ponteiro e comprimento - isso é propenso a erros, dado que cada linguagem representa fatias vazias de maneira ligeiramente diferente)
    • Ponteiros inteligentes como std::unique_ptr<T>, std::shared_ptr<T> e/ou Box são suportados nativamente. Com bindings manuais, seria necessário passar ponteiros brutos (raw pointers) compatíveis com C-ABI, o que aumentaria os riscos de tempo de vida e segurança de memória.
    • Os tipos rust::String e CxxString entendem e mantêm as diferenças na representação de strings entre as linguagens (por exemplo, rust::String::lossy pode construir uma string Rust a partir de uma entrada não UTF8 e rust::String::c_str pode terminar uma string com NUL).