Writing such library will I have to sacrifice std? How, for example, will do I write python bindings to rust library, if possible?
Asked
Active
Viewed 5,873 times
27
-
3Short version: it's just as good as C, better in most places. The long version I am not well suited to writing, but I've pinged someone who's worked with Ruby/Rust interop (Yehuda Katz, for [Skylight](http://skylight.io).) – Chris Morgan May 21 '14 at 13:07
1 Answers
44
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
orBox<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 aVec<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.

Vladimir Matveev
- 120,085
- 34
- 287
- 296

Yehuda Katz
- 28,535
- 12
- 89
- 91
-
7While structs are currently C-compatible in layout, they will not be for much longer, by default; [an RFC was just accepted which will change the layout to undefined unless you use `#[repr(C)]` on the struct](https://github.com/rust-lang/rfcs/blob/0fc8bc0a2d098dc6f007e53f5da20cf11934a297/active/0018-undefined-struct-layout.md). – Chris Morgan May 22 '14 at 02:15
-
Isn't `core::raw::Vec
` the representation for an old-style `~[T]` vector? I think `Vec – May 23 '14 at 16:00` proper now has a different representation (`{length,capacity,pointer-to-array-of-T}` instead of `pointer-to-{length,capacity,array-of-capacity-Ts}`). -
Could you give example code? I'm not sure I follow. I write library in Rust, make some functions "C"-like, and those functions later can be used to, say, making python bindings, because from python point of view this functions are indistinguishable from ordinary C functions, correct? – Moonwalker May 25 '14 at 18:00
-
So it is safe to have a `pub extern` function that returns a `Box
` and then receive the same value from C code as `&T`/`&mut T`? Doesn't require conversion? (Makes sense if the internal representation of a `Box – zstewart Oct 24 '15 at 06:08` *really is* a zero cost abstraction). I guess I'll just try it and see.