Обработка ошибок CXX: пример с QR-кодом
Генератор QR-кодов — пример, где логическое значение используется для передачи успеха или неудачи, а успешный результат может быть передан через границу FFI:
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
#[cxx::bridge(namespace = "qr_code_generator")]
mod ffi {
extern "Rust" {
fn generate_qr_code_using_rust(
data: &[u8],
min_version: i16,
out_pixels: Pin<&mut CxxVector<u8>>,
out_qr_size: &mut usize,
) -> bool;
}
}
Студентов может заинтересовать семантика выходного параметра out_qr_size. Это не размер вектора, а размер QR-кода (и, честно говоря, это немного избыточно — это квадратный корень из размера вектора).
Стоит обратить внимание на важность инициализации out_qr_size перед вызовом функции Rust. Создание ссылки Rust, которая указывает на неинициализированную память, приводит к неопределённому поведению (в отличие от C++, где UB возникает только при самом разыменовании такой памяти).
Если студенты спросят про Pin, объясните, зачем CXX нужен Pin для изменяемых ссылок на данные C++: дело в том, что данные C++ нельзя перемещать, как данные Rust, потому что они могут содержать самоссылающиеся указатели.