Generate Rust ffi bindings to C++ library

Viewed 863

I'm trying to use the cxx crate to generate rust bindings for helios_dac. The DAC code is pretty much just a header file (HeliosDAC.h) and an implementation (HeliosDAC.cpp). It also depends on libusb.h but we'll burn that bridge when we get to it.

Here is my buiild script:

//build.h

fn main() {
    cxx_build::bridge("src/lib.rs")
        .cpp(true)
        .file("src/HeliosDac.cpp")
        .flag_if_supported("-std=c++14")
        .flag_if_supported("-fPIC")
        .compile("helios-bridge");

    println!("cargo:rerun-if-changed=src/lib.rs");
    println!("cargo:rerun-if-changed=src/HeliosDac.cpp");
    println!("cargo:rerun-if-changed=src/HeliosDac.h");
}

And here is my bridge code:

//lib.rs

#[cxx::bridge]
mod ffi {
    extern "C" {
        include!("helios/src/HeliosDac.h");

        type HeliosDac;
        // Functions implemented in C++.
        fn HeliosDac() -> UniquePtr<HeliosDac>;
        fn OpenDevices() -> i32;
        fn CloseDevices() -> i32;
        //fn WriteFrame(devNum: u32, pps: u32, flags: u8)
    }

    extern "Rust" {
    }
}


#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
        let ndevs = ffi::OpenDevices();
        println!("{}", ndevs);
    }
}

The code is organized as follows.

helios/
    build.rs
    src/
        HeliosDac.cpp
        HeliosDAC.h
        libusb.h
        lib.rs

When I run cargo build the compiler tries its best to help me out but I can't understand. For every "C" function I implement it gives a warning about the function name not being in scope:

cargo:warning=   int32_t (*CloseDevices$)() = CloseDevices;
cargo:warning=                                ^~~~~~~~~~~~

And it even gives me a suggestion:

note: suggested alternative: ‘CloseDevices$’

So it can see a function name but there's an extra ampersand on the end? Can someone explain to a newb what's going on here?

0 Answers
Related