Ejercicio: Interoperabilidad con C++
Primera parte
- En el archivo de Rust que has creado anteriormente, añade un
#[cxx::bridge]
, que especifica una sola función, denominadahello_from_rust
, a la que se llamará desde C++, sin parámetros y sin devolver ningún valor. - Modifica la función
hello_from_rust
anterior para eliminarextern "C"
y#[no_mangle]
. Ahora es solo una función estándar de Rust. - Modifica el elemento de destino de
gn
para compilar estos enlaces. - En el código C++, elimina la declaración de
hello_from_rust
. En su lugar, incluye el archivo de encabezado que se ha generado. - Compila y ejecuta.
Segunda parte
Se recomienda jugar un poco con CXX, ya que nos ayuda a pensar en la flexibilidad que tiene Rust en Chromium.
Algunas cosas que probar:
- Vuelve a llamar a C++ desde Rust. Necesitarás lo siguiente:
- Un archivo de encabezado adicional que puedes
include!
desde tucxx::bridge
. Deberás declarar la función de C++ en el nuevo archivo de encabezado. - Un bloque
unsafe
para llamar a una función de este tipo, o bien especificar la palabra claveunsafe
en el#[cxx::bridge]
, como se describe aquí. - Es posible que también tengas que incluir
#include "third_party/rust/cxx/v1/crate/include/cxx.h"
- Un archivo de encabezado adicional que puedes
- Transfiere una cadena de C++ desde C++ a Rust.
- Pasa una referencia a un objeto de C++ en Rust.
- Obtén de forma intencional las firmas de la función de Rust que no coincidan con el
#[cxx::bridge]
y familiarízate con los errores que veas. - Obtén de forma intencional las firmas de la función de C++ que no coincidan con el
#[cxx::bridge]
y familiarízate con los errores que veas. - Transfiere un
std::unique_ptr
de algún tipo de C++ a Rust, para que a Rust le pertenezca algún objeto de C++. - Crea un objeto de Rust y transmítelo a C++ para que sea su propietario. (Nota: necesitas utilizar un
Box
). - Declara algunos métodos en un tipo de C++. Llámalos desde Rust.
- Declara algunos métodos en un tipo de Rust. Llámalos desde C++.
Tercera parte
Ahora que conoces los puntos fuertes y las limitaciones de la interoperabilidad de CXX, piensa en un par de casos prácticos de Rust en Chromium en los que la interfaz sea bastante sencilla. Haz un boceto sobre cómo definirías esa interfaz.
Dónde obtener ayuda
As students explore Part Two, they're bound to have lots of questions about how
to achieve these things, and also how CXX works behind the scenes.
Estas son algunas de las preguntas que pueden surgir:
- Veo un problema al inicializar una variable de tipo X con el tipo Y, donde X e Y son tipos de funciones. Esto se debe a que la función de C++ no coincide exactamente con la declaración de
cxx::bridge
. - Parece que puedo convertir libremente referencias de C++ en referencias de Rust. ¿Eso no supone ningún riesgo de comportamiento indefinido? En el caso de los tipos opacos de CXX, no, porque su tamaño es cero. Sí supondría un problema de comportamiento indefinido en el caso de los tipos triviales de CXX, aunque el diseño de CXX hace que sea bastante difícil crear un ejemplo así.