# C/C++ Headers Under this section we discuss how to write the C/C++ header files that accompany the Rust FFI library. The Rust-side counterpart of each topic is covered in [FFI Function Signatures](ffi-function-signatures.md) and [Allowed Data Types](allowed-data-types.md). ## Function Declaration Style FFI functions must be exported under C names, that is, they must not go through the C++ name mangling mechanism. In the generated C header file, you need to use the `extern "C"` specifier, the `__cplusplus` macro and macro conditionals to import the declarations correctly, for example: ```c++ #ifdef __cplusplus extern "C" { #endif // __cplusplus CError WFStartup(void); // More FFI functions omitted... #ifdef __cplusplus } // extern "C" #endif // __cplusplus ``` ## Required Header Files The generated C/C++ header files must include the appropriate header files for the types used in the declarations. - In C, the `bool` type is provided by ``. C++ supports `bool` natively and does not need any header file. - In C, the integer types are provided by ``. In C++, they are provided by ``. - In C, the `uintptr_t` and `intptr_t` types are provided by ``. In C++, they are provided by ``. - The floating-point types do not require any header file. ## Type Correspondences The following table shows the correspondence between the Rust types that can cross the FFI boundary directly (listed in [Allowed Data Types](allowed-data-types.md)) and their C/C++ counterparts. The left column lists the Rust type and the right column lists the corresponding C/C++ type. | Rust | C/C++ | |------|-------| | `bool` | `bool` | | `f32` | `float` | | `f64` | `double` | | `i8` | `int8_t` | | `i16` | `int16_t` | | `i32` | `int32_t` | | `i64` | `int64_t` | | `u8` | `uint8_t` | | `u16` | `uint16_t` | | `u32` | `uint32_t` | | `u64` | `uint64_t` | | `usize` | `uintptr_t` | | `isize` | `intptr_t` | ## The char Problem For the Rust `char` type, the C/C++ header side uses `char32_t` as the parameter type. Note that `char32_t` can hold any 32-bit unsigned integer, which is broader than the set of valid Unicode scalar values carried by the Rust `char` type. The Rust side is responsible for validating the incoming value; see [The char Problem](allowed-data-types.md#the-char-problem) in [Allowed Data Types](allowed-data-types.md).