gRust Rust FFI

FFI is an extremely powerful mechanism in programming, and it plays an important role in our Source Server gRust. In this post we'll explain a little bit about FFI in Rust, why we chose to utilise it in gRust, and how it speeds up development of the project.

Harry Kerr

2 min read

FFI, quite possibly one of the nicest features of Rust, yet it can be one of the most difficult at the same time.

This dev blog is going to be pretty short and will just detail the move over to FFI for stuff that Rust can't do the same as C/C++ or without taking a year to port the library over to Rust.

What is FFI?

FFI is short for the Foreign Function Interface, it lets us use functions within another language's library without having to port the code over to Rust. So our workflow for moving libraries from source over to FFI is pretty simple in comparison to how complicated it can be:
1) Isolate what libraries we want to use
2) Shrink them down usually into one Header and Source file.
3) Make them platform independent, or provide options for Linux and windows (as we're developing on windows and deploying to Linux)
4) Convert valve's use of inlines
4) Create a new cargo project, add CC and Bindgen build dependencies
5) Write out a quick wrapper around the libraries we've isolated.
6) Enjoy, features have been exported.

Why FFI?

When transferring BitBuf (the network encoding library) from source I realised it'd take too long to make this idiomatic, and fit our code base, so I decided to create it it's own crate and bring over the library that way. That way I can ensure that the networking protocol is going to be the exact same, so we can eliminate any issues when connecting from the Garry's Mod client.

Useful Tools

Some useful tools I've found that I touched on quickly earlier, are: Bindgen and CC. Bindgen is great for generating a binding from a header file along with populating it with the names required for linking. Next up we have CC quite possibly my favourite Rust crate, it generates a library for Rust to link with at build time (Quite good for cross platform) based on what files you've provided it.

Useful articles I found while building our first project:
https://medium.com/dwelo-r-d/using-c-libraries-in-rust-13961948c72a
https://github.com/alexcrichton/cc-rs
https://rust-lang.github.io/rust-bindgen/