Recent Chats
Sign in to access your chat history.
How do I call C from Rust? Find some interesting examples in existing repos and include it in your answer
Details
Answer
Calling C code from Rust is a common practice, especially when you need to interface with existing C libraries or when you need to write performance-critical code. Rust provides a foreign function interface (FFI) to make this possible.
Here's how you can call C from Rust:
extern "C"
blockThe extern "C"
block is the most direct way to declare C functions in Rust. This tells the Rust compiler that the functions inside the block are defined elsewhere and use the C ABI.
Here's an example from the ferrocene/ferrocene
repository:
In this example, my_c_function
is a C function that takes an integer and a C string as arguments and returns an integer. The c_char
and c_int
types are from the std::os::raw
module and correspond to the C char
and int
types, respectively.
cc
crateThe cc
crate is a build dependency that makes it easy to compile C, C++, and assembly code from a build.rs
script. This is the recommended way to build C code from a Rust project.
Here's an example from the rust-lang/rust
repository build.rs:2-2:
In this example, the build.rs
script compiles the foo.c
file and links it to the Rust project. The cc::Build::new()
function creates a new build configuration, the file()
method adds a C file to the build, and the compile()
method compiles the C code and links it to the Rust project.
bindgen
crateThe bindgen
crate is a tool that automatically generates Rust FFI bindings to C and C++ libraries. This is a very useful tool when you need to interface with a large C library.
Here's an example of how you can use bindgen
in your build.rs
script:
In this example, the build.rs
script generates Rust bindings for the C functions declared in the wrapper.h
file and writes them to the bindings.rs
file. The bindgen::Builder::default()
function creates a new builder, the header()
method sets the header file to use, the parse_callbacks()
method sets the callbacks to use, and the generate()
method generates the bindings.
Here are some interesting examples of C code being called from Rust in existing repositories:
rust-lang/rust
: The Rust compiler itself uses the cc
crate to compile C code for the LLVM and compiler-rt libraries build.rs:172-172.tikv/tikv
: The TiKV project uses the cc
crate to compile C++ code for the RocksDB library build.rs:50-50.These are just a few examples of how you can call C from Rust. For more information, you can refer to the official Rust documentation on FFI.