How to use .dll libs created by rust

Shared/Dynamic libraries are just libraries. You need to write a header file that matches the prototypes you export for use in other languages. Since the export will be C (due to the C++ ABI being a problem), you'll want to write out the prototypes as C types.

It really depends on what you wrote, and I can't remember all of the details off the top of my head, but taking the example and modifying it ever so slightly:

use std::thread;

#[no_mangle]
pub extern fn process(count: usize) {
    let handles: Vec<_> = (0..count).map(|_| {
        thread::spawn(|| {
            let mut x = 0;
            for _ in 0..5_000_000 {
                x += 1
            }
            x
        })
    }).collect();

    for h in handles {
        println!("Thread finished with count={}",
        h.join().map_err(|_| "Could not join a thread!").unwrap());
    }
}

I just spun up a new crate and added:

[lib]
name = "dlltest"
crate-type = ["dylib"]

And a quick, hacky, MSVC application to test it:

// Cross-platform bootstrap
#if defined(_WIN32) || defined(_WIN64)
#	ifdef __GNUC__
#		define API_EXPORT __attribute__ ((dllexport))
#		define API_IMPORT __attribute__ ((dllimport))
#	else
#		define API_EXPORT __declspec(dllexport)
#		define API_IMPORT __declspec(dllimport)
#	endif
#       define API_STATIC
#else
#	ifdef __GNUC__
#		define API_EXPORT __attribute__((visibility ("default")))
#		define API_IMPORT __attribute__((visibility ("default")))
#	else
#		define API_EXPORT
#		define API_IMPORT
#	endif
#   define API_STATIC
#endif

extern "C" {
	API_IMPORT void process(size_t count);
}

int main(int argc, char **argv)
{
	process(15);
	return 0;
}

The ifdef in the C++ is probably out of date, I pulled it from an old snippet to bootstrap because I didn't want to restrict to a single platform. Chances are you want attribute on everything these days, but since it's from when I used to use g++ on Linux (and almost never Clang), it's probably dated.


Edit: To be clear, the "header" content is this:

extern "C" {
	API_IMPORT void process(unsigned int count);
}

I took the prototype from Rust and made it into a C prototype. There's nothing particularly special about it, save that usize becomes unsigned int, and the return value not being specified in Rust is void. The rest of what I didn't say is basic C++/Rust programming.