4 Advanced FFI

 

This chapter covers

  • Creating an NGINX extension module with Rust
  • Generating Rust bindings for an existing C codebase
  • Using a C memory allocator from Rust
  • Sharing functions between Rust crates

The previous chapter centered around a simple example of calling a Rust function from C code. We used a single C stack–allocated string value from our Rust code, but the Rust code did not send any heap-allocated values to the C code, nor did it call any C functions. The API surface of our C calculator program was very small, and thus it was quite straightforward to add Rust to it. This chapter is an extension of the previous chapter’s calculator example. Instead of adding our calculator function to a simple CLI application, we’re going to write an NGINX extension module that responds to HTTP requests with calculation results. This chapter is not intended as a general guide on writing NGINX extensions; NGINX is simply a stand-in for a sufficiently complex C codebase to which we want to add some Rust code.

Our goal is to create a module for NGINX that solves Reverse Polish Notation (RPN) math expressions using the calculate library that we created in chapter 3. It should read the expressions from the request POST body. So, assuming that the NGINX server is running on port 8080, it should be usable like this:

$ curl -X POST -d '3 4 +' http://localhost:8080/calculate
7
$ curl -X POST -d '3 4 * 2 -' http://localhost:8080/calculate
10

4.1 Downloading the NGINX source code

4.2 Creating the NGINX module

4.3 Linking C to Rust

4.3.1 Build scripts

4.3.2 bindgen

4.4 Reading the NGINX request

4.4.1 Lifetime annotations

4.4.2 Lifetime annotations in our NGINX plugin

4.5 Using our calculator library

4.6 Writing the HTTP response

Summary