Home About Eric Topics SourceGear

2023-01-18 12:00:00

Multiplying two integers from Rust

This is part of a series on Native AOT.
Previous -- Top -- Next


Rust has a really nice feature called raw-dylib, which allows calling external functions without linking at build time. Given the name of the shared library, Rust will dynamically load the library and lookup the function. (At the time of this writing, raw-dylib is supported only on Windows.)

So, because of this raw-dylib feature, Rust is one of the simpler examples of how to invoke our trivial multiply() function. We just need to declare the extern function signature and include a link attribute to let Rust know that the function should be found in a shared library with the base name "mul":

#[link(name="mul", kind="raw-dylib")]
extern {
    fn multiply(a : i32, b : i32) -> i32;
}

FWIW, raw-dylib in Rust is basically the same feature as P/Invoke in .NET:

[DllImport("mul")]
static extern int multiply(int a, int b);

Anyway, once the declaration is in place, we can call the function from Rust, keeping in mind that Rust considers any FFI function to be unsafe:

fn main() {
    let c = unsafe { multiply(7, 6) };

    println!("{}", c);
}

Of course, the program will complain if it can't find the dynamic library:

$ cargo run
   Compiling mul_rs_win_dynamic v0.1.0 (C:\Users\eric\dev\native-aot-samples\mul_rs_win_dynamic)
    Finished dev [unoptimized + debuginfo] target(s) in 0.41s
     Running `target\debug\mul_rs_win_dynamic.exe`
error: process didn't exit successfully: `target\debug\mul_rs_win_dynamic.exe` 
    (exit code: 0xc0000135, STATUS_DLL_NOT_FOUND)
C:/Users/eric/.cargo/bin/cargo.exe: error while loading shared libraries: 
    ?: cannot open shared object file: No such file or directory

But once mul.dll (built with Native AOT in the previous chapter) is copied into place, we can finally multiply two numbers from Rust:

$ cp ../mul_cs/bin/Debug/net7.0/win-x64/publish/mul.dll .

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target\debug\mul_rs_win_dynamic.exe`
42

The code for this blog entry is available at:

https://github.com/ericsink/native-aot-samples/tree/main/mul_rs_win_dynamic