Rust Daily Learning - Day 23
- Overview
- Creating a C Library
- Defining Rust FFI Bindings
- Calling C Functions from Rust
- Exposing Rust Functions to C
Overview
In today’s Rust daily learning series, we’ll introduce you to the Foreign Function Interface (FFI) in Rust. FFI allows you to create and use bindings between Rust and other programming languages, such as C and C++. This can be valuable for leveraging existing libraries or integrating Rust into existing projects.
Creating a C Library
First, let’s create a simple C library. Create a new directory called c_lib
and add a file named c_functions.h
with the following content:
#ifndef C_FUNCTIONS_H
#define C_FUNCTIONS_H
int add(int a, int b);
#endif
Next, create a file named c_functions.c
with the following content:
#include "c_functions.h"
int add(int a, int b) {
return a + b;
}
Compile the C library using the following command:
gcc -c c_functions.c -o c_functions.o
ar rcs libc_functions.a c_functions.o
This creates a static library named libc_functions.a
.
Defining Rust FFI Bindings
Now, create a new Rust project:
cargo new rust_ffi_example
Change into the rust_ffi_example
directory:
cd rust_ffi_example
Add the libc
crate to your Cargo.toml
file:
[dependencies]
libc = "0.2"
Create a new directory named c_lib
inside the Rust project and copy the c_functions.h
and libc_functions.a
files into it.
Edit the src/main.rs
file to define Rust FFI bindings:
extern crate libc;
use libc::c_int;
#[link(name = "c_functions", kind = "static")]
extern "C" {
fn add(a: c_int, b: c_int) -> c_int;
}
Calling C Functions from Rust
Now, you can call the C add
function from Rust:
fn main() {
let a = 5;
let b = 7;
let result = unsafe { add(a, b) };
println!("The sum of {} and {} is: {}", a, b, result);
}
Build and run your project:
cargo run
Exposing Rust Functions to C
You can also expose Rust functions to C. Edit the src/lib.rs
file and add the following content:
#[no_mangle]
pub extern "C" fn multiply(a: i32, b: i32) -> i32 {
a * b
}
Update the Cargo.toml
file to build a dynamic library:
[lib]
name = "rust_ffi_example"
crate-type = ["cdylib"]
Build the Rust library:
cargo build --release
Create a C file named main.c
inside the c_lib
directory with the following content:
#include <stdio.h>
#include "c_functions.h"
extern int multiply(int a, int b);
int main() {
int a = 5;
int b = 7;
int sum = add(a, b);
int product = multiply(a, b);
printf("The sum of %d and %d is: %d\n", a, b, sum);
printf("The product of %d and %d is: %d\n", a, b, product);
return 0;
}
Compile and link the C program with the Rust library:
gcc main.c -I. -L../rust_ffi_example/target/release -lrust_ffi_example -o main
Run the C program:
./main
You should see the output from both the C add
function and the Rust multiply
function.
That’s it for today’s lesson on Rust and the Foreign Function Interface (FFI). Keep experimenting with FFI and explore how you can use it to leverage existing libraries and integrate Rust code into your projects. Happy coding!