Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Обработка ошибок 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, потому что они могут содержать самоссылающиеся указатели.