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++.
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/ouBox
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
eCxxString
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 erust::String::c_str
pode terminar uma string com NUL).