CXX Error Handling: PNG Example
PNG デコーダのプロトタイプは、成功した結果を FFI の境界を越えて渡せない場合に何ができるかを示しています。
#[cxx::bridge(namespace = "gfx::rust_bindings")]
mod ffi {
extern "Rust" {
/// これは `Result<PngReader<'a>,()>` と同等の FFI 対応の結果を
/// 返します。
fn new_png_reader<'a>(input: &'a [u8]) -> Box<ResultOfPngReader<'a>>;
/// `crate::png::ResultOfPngReader` 型の C++ バインディング
type ResultOfPngReader<'a>;
fn is_err(self: &ResultOfPngReader) -> bool;
fn unwrap_as_mut<'a, 'b>(
self: &'b mut ResultOfPngReader<'a>,
) -> &'b mut PngReader<'a>;
/// `crate::png::PngReader` 型の C++ バインディング
type PngReader<'a>;
fn height(self: &PngReader) -> u32;
fn width(self: &PngReader) -> u32;
fn read_rgba8(self: &mut PngReader, output: &mut [u8]) -> bool;
}
}
PngReader
と ResultOfPngReader
は Rust 型です。これらの型のオブジェクトは、Box<T>
を介さずに FFI 境界を越えることはできません。CXX では Rust オブジェクトを値で格納できないため、out_parameter: &mut PngReader
と書くことはできません。
この例は、CXX が任意のジェネリクスやテンプレートをサポートしていなくても、手動で非ジェネリック型に特化 / 単相化することで、FFI 境界を越えて渡せることを示しています。この例では、ResultOfPngReader
はResult<T, E>
の適切なメソッド(is_err
、unwrap
、as_mut
など)に渡される非ジェネリック型です。