
Ask HN: Do you have experience converting a C library to Rust? - brian-armstrong
I&#x27;m curious what my options are for converting a C library to Rust if a) I want it to maintain the same external interface and b) I don&#x27;t want to do all the work of converting upfront. Is there anything to be aware of for a codebase that&#x27;s half Rust, half C? Is the only option for interop using C FFI in Rust?
======
spease
There are a few automotated solutions (eg corrode, c2rust, etc) that others
will undoubtedly mention. These should help with (b).

You can use bindgen to generate Rust bindings for a C library given a header
file. You can use cheddar to generate a C header file for Rust code with
extern fns. This should help with (a).

So you could set up cheddar, then use bindgen to generate functions which call
the original c library. At this point all the Rust code will be doing is
generating a (hopefully) functionally identical header file for a Rust library
that calls the C library. Then you could run automated tools on the library to
generate Rust functions and move things over function by function. Starting
with the functions that are at the bottom of the dependency tree.

Rust has no significant runtime, no garbage collection, and is intended to run
as fast as C (if you notice any significant deviations, complain on the irc
channel, mailing list, or /r/Rust subreddit). So it should be reasonably
straightforward as long as the C is well formed and you don’t introduce any
stale/null pointer dereferences.

Does that make sense?

EDIT: Also note that there’s a gcc crate you can use to actually build a C
library from source using a Rust buildscript. Depending on how you do things,
you might find it useful.

------
swingline-747
I was just talking to someone about this.

The docs describe the fn call interface here: [https://doc.rust-
lang.org/book/second-edition/ch19-01-unsafe...](https://doc.rust-
lang.org/book/second-edition/ch19-01-unsafe-rust.html#using-extern-functions-
to-call-external-code)

Then you need a .h header. I would include a .la and .pc so other toolchains
can set their options correctly. The build instructions for users would be
something like _cargo build_ or _make_ (which calls cargo).

PS: Mozilla does ;)

~~~
swingline-747
Also, as mentioned, here's a C to Rust transpiler funded by DARPA to help with
migrations [https://c2rust.com/](https://c2rust.com/) RustConf video
[https://youtu.be/WEsR0Vv7jhg](https://youtu.be/WEsR0Vv7jhg) it uses clang and
bindgen under the hood

------
db48x
The general strategy is to port one function to Rust at a time. At first those
functions would be called from C and would call functions written in C, but
the more you port the more your Rust functions would be calling other Rust
functions, so the more scope you would have for using advanced Rust features
like generics, traits, enums, etc.

