# C APIs
C APIs of ROS2 are defined in
[src/msg/humble/runtime_c.rs](https://github.com/tier4/safe_drive/blob/main/src/msg/humble/runtime_c.rs)
and [src/rcl](https://github.com/tier4/safe_drive/tree/main/src/rcl).
These files are generated by Makefile in [supplements/bindgen](https://github.com/tier4/safe_drive/tree/main/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](https://github.com/tier4/safe_drive/blob/main/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.
```rust
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.
```rust
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](https://github.com/tier4/safe_drive/blob/main/src/rcl.rs).
For example, `rcl::rcl_shutdown()` is defined as follows.
```rust
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.
```rust
rcl::MTSafeFn::rcl_shutdown(&mut self.context).unwrap();
```