Interoperabilidad con C

La comunidad de Rust ofrece muchas opciones para la interoperabilidad de C++ y Rust, y continuamente se están desarrollando nuevas herramientas. Actualmente, Chromium usa la herramienta CXX.

Describe todos los límites de tu lenguaje en un lenguaje de definición de interfaz (que se parece mucho a Rust) y, a continuación, las herramientas CXX generarán declaraciones de funciones y tipos tanto en Rust como en 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

Consulta el tutorial de CXX para ver un ejemplo completo de su uso.

Aclara el diagrama. Explica que, en segundo plano, esto hace lo mismo que hemos hecho antes. Señala que automatizar el proceso supone las siguientes ventajas:

  • La herramienta asegura que C++ y Rust coincidan (por ejemplo, se producen errores de compilación si #[cxx::bridge] no coincide con las definiciones de C++ o Rust reales, pero con enlaces manuales no sincronizados, se obtendría un comportamiento no definido)
  • La herramienta automatiza la generación de thunks FFI (funciones pequeñas, compatibles con la ABI de C y gratuitas) para funciones que no son de C (por ejemplo, habilitar llamadas de FFI en métodos de Rust o C++. Los enlaces manuales requerirían la creación manual de estas funciones gratuitas de nivel superior).
  • La herramienta y la biblioteca pueden gestionar un conjunto de tipos principales, como por ejemplo:
    • &[T] se puede transferir a través del límite de FFI, aunque no garantiza ningún diseño concreto de ABI o de memoria. Con los enlaces manuales, std::span<T> y &[T] se tienen que desestructurar manualmente y compilarlos a partir de un puntero y una longitud. Esto suele acarrear errores, ya que cada lenguaje representa los slices vacíos de forma ligeramente distinta.
    • Los punteros inteligentes como std::unique_ptr<T>, std::shared_ptr<T> o Box se admiten de forma nativa. Con los enlaces manuales, sería necesario pasar punteros sin formato compatibles con ABI de C, lo que aumentaría los riesgos de tiempo de vida y de seguridad en la memoria.
    • Los tipos rust::String y CxxString entienden y mantienen las diferencias en la representación de cadenas en los distintos lenguajes (por ejemplo, rust::String::lossy puede crear una cadena de Rust a partir de una entrada que no sea UTF8 y rust::String::: c_str puede terminar una cadena con un carácter nulo).