|
|
|
|
|
by oconnor663
897 days ago
|
|
It really depends. If the interface that you're wrapping can have a nice, abstract API (like "parse this JPEG header into a struct" or something), then the hope is that you can figure out how to express that API in safe Rust, even though underneath it might be a big pile of C. The trouble is when there is no clean API boundary that can fit within safe Rust's rules, like when the underlying C code is "object soup" where everything has pointers to everything else, and it's all up to the programmer to know when it's safe to free things. In that case trying to wrap all that in Rust either gives you unsafe code everywhere, or maybe worse, "safe" APIs that are lying to you and are actually unsound. |
|
This is actually not what you want, because as a rule Safe Rust enforces the use of Rust references which have stricter requirements than C++ references or C/C++/Rust raw pointers, and will otherwise introduce UB. (See the Rustonomicon for a detailed description of those requirements.) A "safe Rust" API is OK when all callers can be proven to satisfy these requirements, otherwise raw pointers are easier even though they must be accessed in an unsafe block.
There are also pitfalls when passing arguments by value to Safe Rust, e.g. a `bool` value MUST be 0 or 1, an `enum` MUST not have an invalid discriminant etc. Breaking any of these requirements when calling Safe Rust from C/C++ makes instant UB a very real possibility.