4 ms·
"A much better alternative is to reuse the original library and just publish a safe interface to it." I think I must reject the premise a bit, unless I misunde
by jacobush 7y ago
"A much better alternative is to reuse the original library and just publish a safe interface to it."
I think I must reject the premise a bit, unless I misunderstand how Rust works.
If you write a safe wrapper around unsafe code, is it not still the case, that if the unsafe code bombs out, it will take the safe Rust down with it, engulfed in shared flames?
(Unless you spawn unsafe code in its separate process or something elaborate like that.)
(Then again, from a practical standpoint the reasoning may be good. Maybe, even likely, the C library is very good and very battle tested. And very likely, my novice would be re-implementation in Rust would not be very good.)
- steveklabnik 7y agoYes, this is an important distinction about "unsafe" in Rust. https://doc.rust-lang.org/nomicon/safe-unsafe-meaning.html https://doc.rust-lang.org/nomicon/safe-unsafe-meaning.html is a good starting place for learning about this.
- estebank 7y agoOne but difference of this approach over just using the original library directly is that now you have a type system that can enforce more invariants than it is possible in C and that the library was previously already relying on. If the (now reduced) API surface happens to still expose a bug, it can both be fixed in the library and/or protected against in the API.
- gbear605 7y agoA lot of the time, the danger with unsafe code is doing a thing like passing a null pointer into a function that can’t handle null pointers, or using something before it is instantiated. So the interface should force those things not to happen (with the type system or a constructor or...). This doesn’t prevent the c code from being buggy, but it makes it much easier to use, since you can ensure that you’re maintaining the invariants.
- SAI_Peregrinus 7y agoAlso even if you do plan to re-implement the C library in Rust it's still a good idea to do this step (make a safe wrapper around the FFI bindings) first. It lets you set up your Rust test cases, and gives you a step to design what the Rust API will look like. You can proceed to pull bits of the C out and into native Rust, all while whatever you've built on top doesn't have to change.