C APIs

C APIs of ROS2 are defined in src/msg/humble/runtime_c.rs and src/rcl. These files are generated by Makefile in supplements/bindgen.

MT Unsafe APIs

MT unsafe APIs requires mutex to prevent data races. So, these MT unsafe APIs must be redefined in MTUnsafeFn in src/rcl.rs. The redefined functions can be called via rcl::MT_UNSAFE_FN, which is a global variable, after locking. For example, rcl::rcl_guard_condition_init() are defined as follows.

#![allow(unused)]
fn main() {
pub(crate) static MT_UNSAFE_FN: Lazy<Mutex<MTUnsafeFn>> =
    Lazy::new(|| Mutex::new(MTUnsafeFn::new()));

pub(crate) struct MTUnsafeFn;

impl MTUnsafeFn {
    pub fn rcl_guard_condition_init(
        &self,
        guard_condition: *mut rcl_guard_condition_t,
        context: *mut rcl_context_t,
        options: rcl_guard_condition_options_t,
    ) -> RCLResult<()> {
        ret_val_to_err(unsafe { self::rcl_guard_condition_init(guard_condition, context, options) })
    }
}
}

It can be called as follows.

#![allow(unused)]
fn main() {
let guard = rcl::MT_UNSAFE_FN.lock();
guard.rcl_guard_condition_init(
    &mut guard_condition,
    unsafe { context.as_ptr_mut() },
    rcl::rcl_guard_condition_options_t { allocator },
)?;
}

MT Safe APIs

MT safe APIs are redefined in MTSafeFn in src/rcl.rs. For example, rcl::rcl_shutdown() is defined as follows.

#![allow(unused)]
fn main() {
pub(crate) struct MTSafeFn;

impl MTSafeFn {
    pub fn rcl_shutdown(context: *mut rcl_context_t) -> RCLResult<()> {
        ret_val_to_err(unsafe { self::rcl_shutdown(context) })
    }
}
}

It can be called without lock as follows.

#![allow(unused)]
fn main() {
rcl::MTSafeFn::rcl_shutdown(&mut self.context).unwrap();
}