cimpl 0.1.1

Adds build time type definitions for C-FFI signature checking
Documentation
cimpl-0.1.1 has been yanked.

cimpl

cimpl is a crate that ensures that the signatures of the functions in C you're implementing matches what C expects.

Why is this useful?

Lets say you have a library in C that requires you to write primitives for it to build up on,

#pragma once

void foo(uint64_t* fill_me);

Now this can be implemented in Rust using your usual C-FFI #[no_mangle] way although it doesn't guarantee any signature changes that may happen in the libraries requirements tomorrow. This results in complete undefined behavior (example: if it changes to void foo(uint32_t* fill_me) tomorrow you could be overflowing buffers 🚨🚨🚨). To ensure against C library fragility at compiletime, cimpl guarantees signature safety as long as the header files for the implementation can be generated at compile-time.

How to use?

build.rs changes

At build time it's required to add the cimpl post-processing step to ensure type definitions can be added into your autogenerated file.

std::fs::write_all(cimpl::derive("<bindgen_output>")).unwrap();

Before

mod bindgen {
    extern "C" {
        pub fn foo() -> i32;
    }
}

After

mod bindgen {
    pub type __cimpl_foo = fn() -> i32;
    extern "C" {
        pub fn foo() -> i32;
    }
}

Implementation

#[cimpl::bind(bindgen::foo)]
#[no_mangle]
pub extern "C" fn foo() -> i32 {
    42_i32
}

This generates the following:

const _: __cimpl_foo = foo; // Guarantees typeck verified signatures at compile-time
#[no_mangle]
pub extern "C" fn foo() -> i32 {
    42_i32
}