Content ideas for a Rust FFI Guide?

(Note: this is a cross-post from reddit)

I've already written a Rust FFI guide of sorts in the past and was thinking it's time to revisit it, potentially rewriting sections or addressing new ideas/techniques, and wanted to get a feel for the things people would find useful.

The guide is mainly meant as a resource for people wanting to integrate Rust code with non-Rust code at the binary level (e.g. a C++ app calling into a Rust crate, or a Rust app pulling in a C DLL), pointing out common patterns and potential footguns.

As such, what sorts of things would people want to know about when writing FFI code? If you are trying to integrate a Rust DLL into something at work, are there any lessons or war stories you'd like to tell others about?

Also, feel free to let me know if you want to help out or otherwise contribute. I'd be happy to add you to the repo as a contributor!

Since the beginning of the year we've introduced Rust to an existing C++ code base, so I dealt with a few integration challenges:

  • There are some C++ libraries built with CMake, for which I added a Cargo.toml and build.rs script that use the cmake and bindgen so they can also be used from Rust. That works well, but Cargo can't automatically know when it needs to re-run the build script. In the end I used walkdir to print a bunch of cargo:rerun-if-changed lines from the build script. This covers most scenarios, but there are still edge cases where I need to manually force a rebuild.

  • I have a Rust crate that is a dependency of both a C++ library and another Rust crate, so I set the crate type to dylib. I always found the distinction between dylib and cdylib confusing, and there are still a few gotchas that folks are likely to run into.

  • The logging in my C++ code isn't too complicated. I just set up a callback so C++ can send a string to the Rust log library. It all gets logged at info level, from a single module, but it's good enough for me.

  • Both bindgen and cbindgen worked without too many issues for me because I kept the FFIs as simple as possible, but I expect others have dealt with more complicated situations.

  • I'm far from an expert with these tools, but one can get a lot of mileage out of some basic knowledge of nm, ldd, and gdb.

Seems to cover only C calling Rust scenario not the other way around which I feel it should also.