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

Customizing bindings using annotations

The Rust bindings for a C++ declaration can be customized using an attribute macro from <crubit/support/annotations.h>.

For instance:

  • A function can be marked unsafe in Rust, even if Crubit would otherwise assume it was safe, using CRUBIT_UNSAFE.
  • Missing bindings for an item can be treated as an error, instead of ignored, using CRUBIT_MUST_BIND.
  • An item can be given a different name in Rust using CRUBIT_RUST_NAME("rust_name_here").

More information:

  • Dependency: //support:annotations
  • Include: #include <crubit/support/annotations.h>
  • Full API documentation: support/annotations.h

Example

Given the following C++ header:

// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef CRUBIT_RS_BINDINGS_FROM_CC_TEST_FUNCTION_UNSAFE_ATTRIBUTES_H_
#define CRUBIT_RS_BINDINGS_FROM_CC_TEST_FUNCTION_UNSAFE_ATTRIBUTES_H_

#include "support/annotations.h"

inline void SafeSignatureWithoutAnnotation() {}
CRUBIT_UNSAFE inline void SafeSignatureButAnnotatedUnsafe() {}

inline void UnsafeSignatureWithoutAnnotation(void*) {}
CRUBIT_UNSAFE_MARK_SAFE inline void UnsafeSignatureButAnnotatedSafe(void*) {}

CRUBIT_OVERRIDE_UNSAFE(/*is_unsafe=*/false) inline void SafeBasedOnBoolean() {}
CRUBIT_OVERRIDE_UNSAFE(/*is_unsafe=*/true) inline void UnsafeBasedOnBoolean() {}

#endif  // CRUBIT_RS_BINDINGS_FROM_CC_TEST_FUNCTION_UNSAFE_ATTRIBUTES_H_

Crubit will generate the following bindings:

// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// Automatically @generated Rust bindings for the following C++ target:
// //examples/cpp/unsafe_attributes:example_lib
// Features: custom_ffi_types, non_unpin_ctor, std_unique_ptr, std_vector, supported

#![rustfmt::skip]
#![feature(allocator_api, cfg_sanitize, custom_inner_attributes)]
#![allow(stable_features)]
#![no_std]
#![allow(improper_ctypes)]
#![allow(nonstandard_style)]
#![allow(dead_code, unused_mut)]
#![deny(warnings)]

/// Generated from: examples/cpp/unsafe_attributes/example.h;l=10
#[inline(always)]
pub fn SafeSignatureWithoutAnnotation() {
    unsafe { crate::detail::__rust_thunk___Z30SafeSignatureWithoutAnnotationv() }
}

/// # Safety
///
/// The C++ function is explicitly annotated as unsafe. Ensure that its safety requirements are upheld.
///
/// Generated from: examples/cpp/unsafe_attributes/example.h;l=11
#[inline(always)]
pub unsafe fn SafeSignatureButAnnotatedUnsafe() {
    crate::detail::__rust_thunk___Z31SafeSignatureButAnnotatedUnsafev()
}

/// # Safety
///
/// The caller must ensure that the following unsafe arguments are not misused by the function:
/// * `__param_0`: raw pointer
///
/// Generated from: examples/cpp/unsafe_attributes/example.h;l=13
#[inline(always)]
pub unsafe fn UnsafeSignatureWithoutAnnotation(__param_0: *mut ::ffi_11::c_void) {
    crate::detail::__rust_thunk___Z32UnsafeSignatureWithoutAnnotationPv(__param_0)
}

/// Generated from: examples/cpp/unsafe_attributes/example.h;l=14
#[inline(always)]
pub fn UnsafeSignatureButAnnotatedSafe(__param_0: *mut ::ffi_11::c_void) {
    unsafe { crate::detail::__rust_thunk___Z31UnsafeSignatureButAnnotatedSafePv(__param_0) }
}

// is_unsafe=

/// Generated from: examples/cpp/unsafe_attributes/example.h;l=16
#[inline(always)]
pub fn SafeBasedOnBoolean() {
    unsafe { crate::detail::__rust_thunk___Z18SafeBasedOnBooleanv() }
}

// is_unsafe=

/// # Safety
///
/// The C++ function is explicitly annotated as unsafe. Ensure that its safety requirements are upheld.
///
/// Generated from: examples/cpp/unsafe_attributes/example.h;l=17
#[inline(always)]
pub unsafe fn UnsafeBasedOnBoolean() {
    crate::detail::__rust_thunk___Z20UnsafeBasedOnBooleanv()
}

// Generated from: nowhere/llvm/src/libcxx/include/__type_traits/integral_constant.h;l=21
// Error while generating bindings for struct 'std::integral_constant<bool, false>':
// Can't generate bindings for std::integral_constant<bool, false>, because of missing required features (crubit.rs-features):
// //examples/cpp/unsafe_attributes:example_lib needs [//features:wrapper] for std::integral_constant<bool, false> (crate::__CcTemplateInstNSt3__u17integral_constantIbLb0EEE is a template instantiation)

// Generated from: nowhere/llvm/src/libcxx/include/__type_traits/integral_constant.h;l=21
// Error while generating bindings for struct 'std::integral_constant<bool, true>':
// Can't generate bindings for std::integral_constant<bool, true>, because of missing required features (crubit.rs-features):
// //examples/cpp/unsafe_attributes:example_lib needs [//features:wrapper] for std::integral_constant<bool, true> (crate::__CcTemplateInstNSt3__u17integral_constantIbLb1EEE is a template instantiation)

mod detail {
    #[allow(unused_imports)]
    use super::*;
    unsafe extern "C" {
        pub(crate) unsafe fn __rust_thunk___Z30SafeSignatureWithoutAnnotationv();
        pub(crate) unsafe fn __rust_thunk___Z31SafeSignatureButAnnotatedUnsafev();
        pub(crate) unsafe fn __rust_thunk___Z32UnsafeSignatureWithoutAnnotationPv(
            __param_0: *mut ::ffi_11::c_void,
        );
        pub(crate) unsafe fn __rust_thunk___Z31UnsafeSignatureButAnnotatedSafePv(
            __param_0: *mut ::ffi_11::c_void,
        );
        pub(crate) unsafe fn __rust_thunk___Z18SafeBasedOnBooleanv();
        pub(crate) unsafe fn __rust_thunk___Z20UnsafeBasedOnBooleanv();
    }
}