The Dark Arts of Advanced and Unsafe Rust Programming
doc.rust-lang.org
doc.rust-lang.org
As advanced as modern languages are, the excellent memory models only work within the language. Interoperability requires that you can work with memory directly when needed. (And only when needed.) I don't have a lot of Rust experience, but C# has plenty of tricks to avoid unsafe code but get close enough to working with real memory.
One thing that would help is if there was some kind of a tool that could take C header files, figure out how the structs and functions compile, and generate the Rust / C# structs and fuction signatures. This is such a time consuming task to do manually in C#, and novices screw it up all the time.
(I wish I had the time to do more work in Rust. It's a great concept!)
* https://github.com/rust-lang-nursery/rust-bindgen - Inputs are C/C++ headers, outputs are Rust type definitions and extern functions to interoperate with the type and functions in the headers
* https://github.com/immunant/c2rust - Inputs are C headers and source, outputs Rust code that is semantically equivalent to the C (modulo bugs, etc.)
* https://github.com/eqrion/cbindgen/ - Inputs are Rust source, outputs C/C++ headers that can be used to interoperate with the types and functions exposed by Rust
http://programatica.cs.pdx.edu/House/
Likewise, metaprogramming routines that generate C code or interfaces for you from language statements closer to host.
I have been playing with idea but often you also need to know what the function does with the pointer you pass in. Is it "in", "out" or whatever? With a lot of functions it would be doable but there are quite a few Win32 functions where it's really, really hard to do direct interop from C#. For these cases I find C+/CLI wrappers easier to deal with.
I'm using bindgen in a project to bind the Linux kernel headers, which makes me a little bit uncomfortable because the Linux kernel is only guaranteed to compile with GCC (and may use GCC-specific extensions in describing structure layout) and in particular there's no guarantee that the in-kernel ABI is stable across different compilers. But it seems to work well in practice, as long as I tell bindgen not to attempt to parse literally everything (which it fails at).
That said - if you're interoperating with memory-mapped IO or with memory mapped from a foreign process, the other thing to be very careful about is that almost all languages (including C!) by default only make sure that memory writes are coherent from the viewpoint of other code in that language, and not necessarily that they're coherent from the viewpoint of something looking directly at memory. It's generally permissible to write a 64-bit number by writing each 32-bit half separately. It's generally permissible to write something and overwrite it immediately, or combine multiple writes, or so forth. In addition to structure layout, you probably want volatile read/write operations, same as you'd want volatile pointers in C: https://doc.rust-lang.org/std/ptr/fn.read_volatile.html or the atomic types with the "SeqCst" barrier https://doc.rust-lang.org/std/sync/atomic/index.html .
Unfortunately, they're not done yet. A guy I bumped into at a Linux kernel conference once said that their main issue is that some people within the kernel project want to keep GCC as the only way to compile the kernel.
You usually run into the problem that the header files include other header files and you get this long dependency chain where somewhere in the chain some type is not recognized by the converter, to solve this the best is to cherry-pick the dependent types from the included header files and just put everything into one big flat header before passing into the tool. Macros can also be a PITA that you have to rewrite into functions and constants before generating.
You also have http://pinvoke.net/ with almost all win32 functions wrapped already. Same there though, review before use because it's a wiki and the quality is varying.
Is there a resource like The Rustonomicon, but written in a concise and formal style?
Not sure how to search to get a collection of the unsafe related functions though.
[1] https://github.com/rust-lang-nursery/nomicon/commits/master
Rust is nothing but a slapdash C style copy of its semantics.
Rust is a copy of Ada's semantics for dealing with memory unsafe code? Could you provide an example of what you mean?
> Ada does, and has better and more clear conventions for "unsafe" programming (pointer arithmetic, conversions, etc)
Can you give some examples here of what you mean? I found Interfaces.C.Pointers, but I don't know enough about the language to know if that's what you were talking about
Have you ever actually looked at rust? The headline feature of Rust is linear types with checked borrowing, something that Ada does not provide.