Giter Club home page Giter Club logo

embed-c's Introduction

embed-c

embed-c is a crate that allows you to embed C code inside Rust code files. The C code is translated into Rust code at compile time using C2Rust, which means that it is fully interoperable with Rust. C code can call Rust code, and vice-versa.

Basic usage

#![feature(rustc_private)] 

use embed_c::embed_c;

embed_c! {
    int add(int x, int y) {
        return x + y;
    }
}

fn main() {
    let x = unsafe { add(1, 2) };
    println!("{}", x);
}

Install

The library is not yet on crates.io. Clone the repository somewhere and set it up:

git clone https://github.com/zdimension/embed-c.git
cd embed-c
git submodule update --init c2rust
cp Cargo.lock ..
cd ..

and add this to your Cargo.toml:

[dependencies]
embed-c = { path = "./embed-c", version = "0.1" }

[patch.crates-io]
c2rust-transpile = { path = "./embed-c/c2rust/c2rust-transpile" }

NOTE: this crate is designed to work for the nightly-2019-12-05 version of Rust, so put this in your rust-toolchain.toml:

[toolchain]
channel = "nightly-2019-12-05"

And change the package.edition setting in your Cargo.toml to be "2018":

[package]
edition = "2018"

If you get errors about the matches! macro, or from the half or rustc_demangle crates, copy the Cargo.lock file to your project root again.

Usage details

The example at the top is translated into:

#[no_mangle]
pub unsafe extern "C" fn add(mut x: libc::c_int, mut y: libc::c_int)
 -> libc::c_int {
    return x + y;
}

fn main() {
    let x = unsafe { add(1, 2) };
    println!("{}", x);
}

The #![feature(rustc_private)] bit is required since the crate uses internal features while not being loaded from crates.io.

See more examples in src/lib.rs.

embed_c! {
    void send(to, from, count)
        register short *to, *from;
        register count;
    {
        register n = (count + 7) / 8;
        switch (count % 8) {
        case 0: do { *to++ = *from++;
        case 7:      *to++ = *from++;
        case 6:      *to++ = *from++;
        case 5:      *to++ = *from++;
        case 4:      *to++ = *from++;
        case 3:      *to++ = *from++;
        case 2:      *to++ = *from++;
        case 1:      *to++ = *from++;
                } while (--n > 0);
        }
    }
}

fn main() {
    let mut source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    let mut dest = [0; 10];
    unsafe { send(dest.as_mut_ptr(), source.as_mut_ptr(), 10); };
    assert_eq!(source, dest);
}

Here, the send function becomes:

#[no_mangle]
pub unsafe extern "C" fn send(mut to: *mut libc::c_short,
                              mut from: *mut libc::c_short,
                              mut count: libc::c_int) {
    let mut n: libc::c_int = (count + 7 as libc::c_int) / 8 as libc::c_int;
    let mut current_block_7: u64;
    match count % 8 as libc::c_int {
        0 => { current_block_7 = 8258075665625361029; }
        7 => { current_block_7 = 8412423308551259261; }
        6 => { current_block_7 = 15077176690991321518; }
        ...
        1 => { current_block_7 = 14053040055230693409; }
        _ => { current_block_7 = 13586036798005543211; }
    }
    loop  {
        match current_block_7 {
            13586036798005543211 => { return; }
            8258075665625361029 => {
                let fresh0 = from;
                from = from.offset(1);
                let fresh1 = to;
                to = to.offset(1);
                *fresh1 = *fresh0;
                current_block_7 = 8412423308551259261;
            }
            8412423308551259261 => ...
            ...
            _ => {
                let fresh14 = from;
                from = from.offset(1);
                let fresh15 = to;
                to = to.offset(1);
                *fresh15 = *fresh14;
                n -= 1;
                if n > 0 as libc::c_int {
                    current_block_7 = 8258075665625361029;
                } else { current_block_7 = 13586036798005543211; }
            }
        }
    };
}

As you can see, the interweaved switch-do construct is transpiled into a very idiomatic Rust function through the use of pattern matching. You may not like it, but this is what peak functional programming looks like.

Limitations

Many

Motivation

N/A

License

This project is licensed under either of

embed-c's People

Contributors

zdimension avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.