In Rust document, FFI seems to be easy and very similar to .Net DllImport.... but in reality it's a different story! My first attempt was to use compiler directive #![link] but it failed from incorrect usage. I later found out there are already Win32 ported in crate.io so instead to research on correct FFI implementation, I've decided to use them and it's still hard to use.
Anyway, after one day of trial & error, I finally managed the "Hello, world!" code to work!
extern crate winapi;
extern crate user32;
use std::ptr::{null_mut};
fn w16str(s: &str) -> Vec {
let mut w16: Vec = s.utf16_units().collect();
w16.push(0);
w16
}
fn main() {
unsafe {
user32::MessageBoxW( null_mut()
, w16str("Hello, world!").as_ptr()
, w16str("Test").as_ptr()
, 0);
}
}
user32 crate builds upon winapi crate, which provides Windows basic system types, so chance is you'll have to also use winapi crate in your code.
The Windows API I use for this experiment is MessageBox, which takes 4 parameters; handle to a parent window, message text, header text, and button config. The window handle can be NULL if it's not needed. I've spent hours just to find the way to instantiate NULL pointer and finally found std::ptr::null_mut() >< ... Perhaps I still do not completely understand Interop types needed.
The second pain point I found was string compatibility. Rust's string is UTF32 by default and Windows API uses Wide String, which is UTF16(? if I don't misunderstand). There is a convenient method to convert Rust string to utf16, the function named utf16_units(), but!!! it is unsafe function so it cannot be used in stable version of Rust. The more I learn about Rust the more I'm not sure whether I'm ready to get though all these hardness .... It seems to me that Rust is still immature in FFI area...
After I've installed Nightly build of Rust, the compiler allows me to use the method and then I can easily convert Rust's string to UTF16 as shown in function w16str(). Finally, the FFI MessageBoxW function is unsafe so it must be wrapped in unsafe block, which is fine. I think I may try to create a Windows application with Rust to see more potential issues. Let's see if I have a chance.