1. 35
  1.  

  2. 23

    If you’re wondering why bother wrapping a C library in Rust instead of just using C — Rust can add safety guarantees even to C code!

    When using a C library you may need to know things such as “if I pass a pointer to the library, who will free it and when?”, “can this be NULL?”, “is this thread-safe?”, “can I call this function more than once?”. In C these things are in the manual, but Rust can express them in the type system. When writing Rust wrappers I literally copy prose from the documentation into Rust type system, and have the compiler enforce RTFM!

    Of course that won’t help for bugs that are deep in the C code, but it is possible to prevent most bugs caused by wrong inputs, incorrect memory management, invalid state, unchecked errors, and unsynchronized cross-thread usage.

    1. 5

      This is how I actually got into Rust. I wrote bindings for leveldb and notmuch and was amazed how easy it was to encode things like “Iterator cannot outlive Database it iterates over” in Rust, which e.g. the leveldb documentation just requires verbally.

    2. 1

      Great writeup. I’m actually considering doing this for a project of mine, so I’ve bookmarked this.

      Normally it’d be better to link with whatever lzx library is installed on the user’s machine so we receive updates

      How would one do this?

      1. 3

        There are helper crates like pkg-config and vcpkg that will find and configure it for you. Underneath it boils down to telling cargo an appropriate lib search path and name of the library to link.

        https://kornel.ski/rust-sys-crate

        1. 1

          thank you, that article’s great too. wow.

        2. 1

          In an attempt to answer my own question, I went searching. Not sure if all of this is relevant:

          1. https://github.com/rust-lang/cargo/issues/3573
          2. https://rufflewind.com/2017-11-19/linking-in-rust (note: from 2017!)
          3. https://github.com/KyleMayes/clang-sys/blob/e3a9fb35d8c10663518538fa48a3e135ca6157f5/build/dynamic.rs#L191 (looks like the second approach from blog post 2.)