Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can rust library be used from another languages in a way c libraries do?

Writing such library will I have to sacrifice std? How, for example, will do I write python bindings to rust library, if possible?

like image 310
Moonwalker Avatar asked May 21 '14 10:05

Moonwalker


People also ask

Can rust use C libraries?

Rust natively supports linking against C libraries and calling their functions directly. Of course, any function imported thus requires the unsafe keyword to actually call (because Rust can't guarantee its invariants or correctness) but that's an inconvenience we can punt until later.

What is rust FFI?

Rust provides a Foreign Function Interface (FFI) to C libraries. Foreign functions must be declared inside an extern block annotated with a #[link] attribute containing the name of the foreign library.


1 Answers

First, indicate to Rust that you want to create a function visible to C:

#[no_mangle] pub extern "C" fn some_func() { ... } 

This tells Rust to avoid mangling the output symbol and to use the C ABI.

Next, you will need to use C-compatible types when crossing the boundary. Here is some advice that has worked for me:

  • If you are planning to pass a Rust structure to C as opaque data, which it will pass back into other functions, return it as a Box<T>, and take it as a &T or Box<T>. Essentially, this means that you are giving up ownership of the structure in Rust, and giving ownership to the C code. The C code must ensure that if it passes the pointer back into a function that takes a Box, it no longer uses it.
  • If you are planning to pass a Rust structure to C as a C structure, Rust conveniently represents its structs in a C-compatible way. However, you will want to restrict the kinds of values you put in these structs to types that also have compatible C representations. Numeric types and booleans are safe, of course.
  • You can see the Rust representation of more complex types (like vecs and strings) in the docs under core::raw. A &str and &[T] are represented as raw::Slice while a Vec<T> is represented as a raw::Vec.
  • You can also convert types into the libc::types
  • Finally, you may find yourself needing to work with pointers directly. Check out std::mem for useful APIs.
like image 145
Yehuda Katz Avatar answered Oct 06 '22 12:10

Yehuda Katz