Automatically generates Rust FFI bindings to C (and some C++) libraries.

Overview

crates.io docs.rs

bindgen

bindgen automatically generates Rust FFI bindings to C (and some C++) libraries.

For example, given the C header doggo.h:

typedef struct Doggo {
    int many;
    char wow;
} Doggo;

void eleven_out_of_ten_majestic_af(Doggo* pupper);

bindgen produces Rust FFI code allowing you to call into the doggo library's functions and use its types:

/* automatically generated by rust-bindgen 0.99.9 */

#[repr(C)]
pub struct Doggo {
    pub many: ::std::os::raw::c_int,
    pub wow: ::std::os::raw::c_char,
}

extern "C" {
    pub fn eleven_out_of_ten_majestic_af(pupper: *mut Doggo);
}

Users Guide

📚 Read the bindgen users guide here! 📚

MSRV

The minimum supported Rust version is 1.40.

No MSRV bump policy has been established yet, so MSRV may increase in any release.

API Reference

API reference documentation is on docs.rs

Environment Variables

In addition to the library API and executable command-line API, bindgen can be controlled through environment variables.

End-users should set these environment variables to modify bindgen's behavior without modifying the source code of direct consumers of bindgen.

  • BINDGEN_EXTRA_CLANG_ARGS: extra arguments to pass to clang
    • Arguments are whitespace-separated
    • Use shell-style quoting to pass through whitespace
    • Examples:
      • Specify alternate sysroot: --sysroot=/path/to/sysroot
      • Add include search path with spaces: -I"/path/with spaces"

Additionally, bindgen uses libclang to parse C and C++ header files. To modify how bindgen searches for libclang, see the clang-sys documentation. For more details on how bindgen uses libclang, see the bindgen users guide.

Releases

We don't follow a specific release calendar, but if you need a release please file an issue requesting that (ping @emilio for increased effectiveness).

Contributing

See CONTRIBUTING.md for hacking on bindgen!

Comments
  • Generated tests use UB in their calculations

    Generated tests use UB in their calculations

    Test code for struct offsets run checks like this:

        assert_eq!(
            unsafe { &(*(::core::ptr::null::<timeval>())).tv_sec as *const _ as usize },
            0usize,
            concat!(
                "Offset of field: ",
                stringify!(timeval),
                "::",
                stringify!(tv_sec)
            )
        );
    

    But it's UB to dereference a null pointer, and it's also UB to create a &T with numeric value 0.

    There is actually trivial to fix. Instead of using a null pointer, just create a value on the stack (using core::mem::zeroed(), which is safe since all C structs can be created as zeroed-memory), and then use a reference to that stack value, the fields of that stack value, and so on.

    enhancement 
    opened by Lokathor 77
  • Split off bindgen library into a sub-crate

    Split off bindgen library into a sub-crate

    • Unfortunately there's a dependency on log via syntex_errors, so we don't get rid of it all
    • I can't find a more sensible way to set dependencies based on whether you're building the lib or bin
    • So --no-default-features means you need to know what you're doing, as only the lib will build without the logging crates for now
    • The replacement log macros are pretty gross too, but they show a proof of concept ;-)
    opened by jdub 75
  • Add dynamic loading support

    Add dynamic loading support

    Hi guys,

    Following on from issue 1541, here's an implementation for libloading support in bindgen. I'd still consider this a prototype at the minute, so any comments are welcome and appreciated.

    Implementation

    • The existing functionality is maintained if dynamic loading mode is not specified.
    • We introduce two new flags -- --dynamic-loading and --dynamic-library-name -- which enable dynamic loading mode and specify a name for the shared library respectively. The 'name' of the shared library is what you want the struct containing the bindings to be called. For example, you could call it BZip2 -- then you'd instantiate the dynamically loaded library with let lib = BZip2::new();. If --dynamic-library-name is not specified it'll just default to Lib.
    • If dynamic loading mode is specified, the bindings are created inside a library struct alongside some libloading boilerplate.

    Example

    Given the following header.h:

    int foo(int x);
    void bar(double x);
    

    And the following code inside our build.rs:

    let bindings = bindgen::Builder::default()
        .header("header.h")
        // Use dynamic loading
        .dynamic_loading(true)
        .dynamic_library_name("MyLibrary")
        // ...
        .generate()
        .expect("Unable to generate bindings");
    

    We generate the following bindings:

    /* automatically generated by rust-bindgen 0.54.1 */
    
    pub struct MyLibrary<'a> {
        foo: libloading::Symbol<
            'a,
            unsafe extern "C" fn(x: ::std::os::raw::c_int) -> ::std::os::raw::c_int,
        >,
        bar: libloading::Symbol<'a, unsafe extern "C" fn(x: f64)>,
    }
    impl<'a> MyLibrary<'a> {
        pub fn new(lib: &libloading::Library) -> MyLibrary {
            unsafe {
                MyLibrary {
                    foo: lib.get("foo".as_bytes()).unwrap(),
                    bar: lib.get("bar".as_bytes()).unwrap(),
                }
            }
        }
    }
    

    Which we can then use in our code with the following:

    #![allow(non_upper_case_globals)]
    #![allow(non_camel_case_types)]
    #![allow(non_snake_case)]
    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
    
    extern crate libloading;
    
    pub fn main() {
        let lib = libloading::Library::new("/path/to/shared/lib.so").unwrap();
        let library_wrapper = MyLibrary::new(&lib);
        unsafe { (library_wrapper.bar)(123.0) };
    }
    

    Multiple Dynamically Loaded Libraries

    If you want to use multiple dynamically loaded libraries, the correct approach would be to do this in your build.rs:

    let bindings_x = bindgen::Builder::default()
        .header("header_x.h")
        // Use dynamic loading
        .dynamic_loading(true)
        .dynamic_library_name("LibraryX")
        // ...
        .generate()
        .expect("Unable to generate bindings");
    
    let bindings_y = bindgen::Builder::default()
        .header("header_y.h")
        // Use dynamic loading
        .dynamic_loading(true)
        .dynamic_library_name("LibraryY")
        // ...
        .generate()
        .expect("Unable to generate bindings");
    
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    lib1_bindings
        .write_to_file(out_path.join("libx_bindings.rs"))
        .expect("Couldn't write bindings!");
    lib2_bindings
        .write_to_file(out_path.join("liby_bindings.rs"))
        .expect("Couldn't write bindings!");
    

    Then do the following in your code:

    extern crate libloading;
    
    mod libx {
        include!(concat!(env!("OUT_DIR"), "/libx_bindings.rs"));
    }
    mod liby {
        include!(concat!(env!("OUT_DIR"), "/liby_bindings.rs"));
    }
    pub use lib1::LibraryX;
    pub use lib2::LibraryY;
    

    (the mod libx { ... } is to prevent namespace collisions if LibraryX and LibraryY have common includes -- e.g. if they both have #include <stdint.h>)


    Comments and criticisms absolutely welcome! If this seems like a suitable approach I can update the docs in a separate PR. Cheers! 🍻

    S-awaiting-review 
    opened by joechrisellis 39
  • Publish the executable on crates.io

    Publish the executable on crates.io

    Since this is a useful library that is used in also many non-servo projects, I think it will be convinient to have it in crates.io. Then also we can do cargo install servo-rust-bindgen .

    opened by kkimdev 34
  • Auto-generated test failure using <link.h> on Debian 9.

    Auto-generated test failure using on Debian 9.

    Input C/C++ Header

    Sorry, I know you asked for no #includes, but I'm at a loss as to what the predicate script should do when I'm just importing types from the C library -- If you can't reproduce from the info below, then could you help me with the predicate script plz? :)

    #define _GNU_SOURCE
    #include <link.h>
    

    Bindgen Invocation

        let bindings = bindgen::Builder::default()
                               .header(WRAPPER_HEADER)
                               .generate()
                               .expect("bindgen failed");
    

    Actual Results

    When included, like this:

    #![allow(non_upper_case_globals)]
    #![allow(non_camel_case_types)]
    #![allow(non_snake_case)]
    #![allow(dead_code)]
    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
    
    $ RUST_BACKTRACE=1 cargo test bindgen_test_layout_La_x86_64_retval
    ---- bindgen_test_layout_La_x86_64_retval stdout ----
    thread 'bindgen_test_layout_La_x86_64_retval' panicked at 'assertion failed: `(left == right)`
      left: `224`,
     right: `240`: Size of: La_x86_64_retval', /home/vext01/research/bg/target/debug/build/bg-29903e2596eaef66/out/bindings.rs:3:221231
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    stack backtrace:
       0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
                 at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
       1: std::sys_common::backtrace::print
                 at libstd/sys_common/backtrace.rs:71
                 at libstd/sys_common/backtrace.rs:59
       2: std::panicking::default_hook::{{closure}}
                 at libstd/panicking.rs:211
       3: std::panicking::default_hook
                 at libstd/panicking.rs:221
       4: std::panicking::rust_panic_with_hook
                 at libstd/panicking.rs:475
       5: std::panicking::continue_panic_fmt
                 at libstd/panicking.rs:390
       6: std::panicking::begin_panic_fmt
                 at libstd/panicking.rs:345
       7: bg::bindgen_test_layout_La_x86_64_retval
                 at ./target/debug/build/bg-29903e2596eaef66/out/bindings.rs:3
       8: bg::__test::TESTS::{{closure}}
                 at ./target/debug/build/bg-29903e2596eaef66/out/bindings.rs:3
       9: core::ops::function::FnOnce::call_once
                 at /checkout/src/libcore/ops/function.rs:223
      10: <F as alloc::boxed::FnBox<A>>::call_box
                 at libtest/lib.rs:1459
                 at /checkout/src/libcore/ops/function.rs:223
                 at /checkout/src/liballoc/boxed.rs:642
      11: __rust_maybe_catch_panic
                 at libpanic_unwind/lib.rs:102
    

    This is the only failing test.

    Expected Results

    Test passes.

    This is on Debian 9 x86_64, using today's Rust nightly.

    FWIW, OpenBSD's <link.h> does work on an OpenBSD system.

    Any ideas?

    opened by vext01 33
  • Add support for 'unsafe fields'

    Add support for 'unsafe fields'

    Needed for the next step of https://github.com/servo/servo/pull/12521

    These are fields which are private but have unsafe accessor functions. Since we generate bindings in a separate module, we can't touch private fields from other parts of the module (an alternative is to inject a footer with these private impls). pub(restricted) exists, but is not stable.

    r? @emilio

    opened by Manishearth 29
  • [WIP] add saltwater backend

    [WIP] add saltwater backend

    Addresses https://github.com/rust-lang/rust-bindgen/issues/1762

    Not expecting this to be merged, just looking for feedback on whether this is the right approach.

    I forgot that the lexer returns its own Locations, so I'm using those just to get a prototype going. I can switch to using the proper clang locations later (although since they are never displayed maybe it won't matter?)

    The lexer currently doesn't allow inputting a single token at a time so I hacked around it by treating the token span as if it were a whole file and assuming there was only one token in the file. I can fix this later, not sure yet how hard it will be on the rcc end.

    All the test cases pass locally. Note that this already could fix https://github.com/rust-lang/rust-bindgen/issues/1594 if I removed the as i64 cast and instead returned a Literal from parse_int_literal_tokens. It looks like bindgen has a VarType so impl From<Literal> for VarType should be pretty simple. It would be nice to add an UnsignedInt variant as well, then the two would match up almost exactly (rcc has no literal boolean values).

    What is parse_macro doing? It looks like it's supposed to parse the entire #define a 1 + 2 directive? Should it also perform macro replacement, and should that include function macros?

    cc @emilio

    S-awaiting-review S-needs-rebase 
    opened by jyn514 28
  • Instantiating a template with a template instantiation (eg Template1<Template2<Type>>) causes us to generate bad bindings

    Instantiating a template with a template instantiation (eg Template1>) causes us to generate bad bindings

    Input:

    template <typename> struct a;
    namespace JS {
    template <typename T> using b = a<T>;
    template <typename T> class Rooted { b<T> c; };
    }
    

    Output with --enable-cxx-namespaces -- --std=c++11:

    /* automatically generated by rust-bindgen */
    
    pub mod root {
        #[allow(unused_imports)]
        use self::super::root;
        #[repr(C)]
        #[derive(Debug, Copy)]
        pub struct a {
            pub _address: u8,
        }
        impl Clone for a {
            fn clone(&self) -> Self { *self }
        }
        pub mod JS {
            #[allow(unused_imports)]
            use self::super::super::root;
            pub type b<T> = root::a;
            #[repr(C)]
            #[derive(Debug, Copy, Clone)]
            pub struct Rooted<T> {
                pub c: root::JS::b<T>,
            }
        }
    }
    

    Compilation errors:

    error[E0392]: parameter `T` is never used
      --> js.rs:20:27
       |
    20 |         pub struct Rooted<T> {
       |                           ^ unused type parameter
       |
       = help: consider removing `T` or using a marker such as `std::marker::PhantomData`
    
    error: aborting due to previous error
    

    I'm not 100% sure what the best thing to do in this case is, but whatever we do the bindings we emit should compile.

    This seems really familiar... I wonder if we regressed something recently?

    bug 
    opened by fitzgen 28
  • Point to the `--whitelist` flags or reporting a bug when we error on binding generation.

    Point to the `--whitelist` flags or reporting a bug when we error on binding generation.

    Running bindgen on the headers of any nontrivial API tends to generate bindings for most of the C/C++ standard library, which is at best undesirable, often doesn’t compile, and sometimes makes even the binding generation fail. The work-around is to use --match to only generate bindings for declarations in relevant header files. (Fortunately, matching can be on a directory name so that there is no need to list each single file individually.)

    So it seems to me that --match is necessary in practice. Running without it should probably print a message explaining all this, rather than leave the user wondering why they have dozens of compiler errors.

    help wanted E-easy C-assigned 
    opened by SimonSapin 27
  • bitfield methods not generated

    bitfield methods not generated

    Some bitfield getters and setter methods which were generated by bindgen 24.x are no longer generated by bindgen 26.x.

    The following is a stripped down branch of my project which reproduces the problem with a single C struct.

    https://github.com/glyn/jvmkill/tree/reproduce-bindgen-bug

    Input C/C++ Header

    typedef struct {
        unsigned int can_tag_objects : 1;
        unsigned int can_generate_field_modification_events : 1;
        unsigned int can_generate_field_access_events : 1;
        unsigned int can_get_bytecodes : 1;
        unsigned int can_get_synthetic_attribute : 1;
        unsigned int can_get_owned_monitor_info : 1;
        unsigned int can_get_current_contended_monitor : 1;
        unsigned int can_get_monitor_info : 1;
        unsigned int can_pop_frame : 1;
        unsigned int can_redefine_classes : 1;
        unsigned int can_signal_thread : 1;
        unsigned int can_get_source_file_name : 1;
        unsigned int can_get_line_numbers : 1;
        unsigned int can_get_source_debug_extension : 1;
        unsigned int can_access_local_variables : 1;
        unsigned int can_maintain_original_method_order : 1;
        unsigned int can_generate_single_step_events : 1;
        unsigned int can_generate_exception_events : 1;
        unsigned int can_generate_frame_pop_events : 1;
        unsigned int can_generate_breakpoint_events : 1;
        unsigned int can_suspend : 1;
        unsigned int can_redefine_any_class : 1;
        unsigned int can_get_current_thread_cpu_time : 1;
        unsigned int can_get_thread_cpu_time : 1;
        unsigned int can_generate_method_entry_events : 1;
        unsigned int can_generate_method_exit_events : 1;
        unsigned int can_generate_all_class_hook_events : 1;
        unsigned int can_generate_compiled_method_load_events : 1;
        unsigned int can_generate_monitor_events : 1;
        unsigned int can_generate_vm_object_alloc_events : 1;
        unsigned int can_generate_native_method_bind_events : 1;
        unsigned int can_generate_garbage_collection_events : 1;
        unsigned int can_generate_object_free_events : 1;
        unsigned int can_force_early_return : 1;
        unsigned int can_get_owned_monitor_stack_depth_info : 1;
        unsigned int can_get_constant_pool : 1;
        unsigned int can_set_native_method_prefix : 1;
        unsigned int can_retransform_classes : 1;
        unsigned int can_retransform_any_class : 1;
        unsigned int can_generate_resource_exhaustion_heap_events : 1;
        unsigned int can_generate_resource_exhaustion_threads_events : 1;
        unsigned int : 7;
        unsigned int : 16;
        unsigned int : 16;
        unsigned int : 16;
        unsigned int : 16;
        unsigned int : 16;
    } jvmtiCapabilities;
    

    Bindgen Invocation

        let bindings = bindgen::Builder::default()
            .header(input.h)
            .generate()
            .expect("Failed to generate bindings");
    
        bindings
            .write_to_file(output.rs)
            .expect("Failed to write bindings");
    }
    

    Actual Results

    Incorrect bindings from bindgen 26.3:

    /* automatically generated by rust-bindgen */
    
    #[repr(C)]
    #[derive(Debug, Copy)]
    pub struct jvmtiCapabilities {
        pub _bitfield_1: [u16; 8usize],
        pub __bindgen_align: [u32; 0usize],
    }
    #[test]
    fn bindgen_test_layout_jvmtiCapabilities() {
        assert_eq!(::std::mem::size_of::<jvmtiCapabilities>() , 16usize , concat !
                   ( "Size of: " , stringify ! ( jvmtiCapabilities ) ));
        assert_eq! (::std::mem::align_of::<jvmtiCapabilities>() , 4usize , concat
                    ! ( "Alignment of " , stringify ! ( jvmtiCapabilities ) ));
    }
    impl Clone for jvmtiCapabilities {
        fn clone(&self) -> Self { *self }
    }
    

    Expected Results

    Correct bindings from bindgen 24.x:

    /* automatically generated by rust-bindgen */
    
    #[repr(C)]
    #[derive(Debug, Copy)]
    pub struct jvmtiCapabilities {
        pub _bitfield_1: [u8; 4usize],
        pub _bitfield_2: [u16; 2usize],
        pub _bitfield_3: [u16; 2usize],
        pub _bitfield_4: [u16; 2usize],
        pub __bindgen_align: [u32; 0usize],
    }
    #[test]
    fn bindgen_test_layout_jvmtiCapabilities() {
        assert_eq!(::std::mem::size_of::<jvmtiCapabilities>() , 16usize , concat !
                   ( "Size of: " , stringify ! ( jvmtiCapabilities ) ));
        assert_eq! (::std::mem::align_of::<jvmtiCapabilities>() , 4usize , concat
                    ! ( "Alignment of " , stringify ! ( jvmtiCapabilities ) ));
    }
    impl Clone for jvmtiCapabilities {
        fn clone(&self) -> Self { *self }
    }
    impl jvmtiCapabilities {
        #[inline]
        pub fn can_tag_objects(&self) -> ::std::os::raw::c_uint {
            let mask = 1usize as u32;
            let field_val: u32 =
                unsafe { ::std::mem::transmute(self._bitfield_1) };
            let val = (field_val & mask) >> 0usize;
            unsafe { ::std::mem::transmute(val as u32) }
        }
        #[inline]
        pub fn set_can_tag_objects(&mut self, val: ::std::os::raw::c_uint) {
            let mask = 1usize as u32;
            let val = val as u32 as u32;
            let mut field_val: u32 =
                unsafe { ::std::mem::transmute(self._bitfield_1) };
            field_val &= !mask;
            field_val |= (val << 0usize) & mask;
            self._bitfield_1 = unsafe { ::std::mem::transmute(field_val) };
        }
        // etc. etc.
    }
    

    RUST_LOG=bindgen Output

    Please see this gist since the log was too long for a github issue body.

    bug help wanted A-bitfields 
    opened by glyn 26
  • Forward declared structs now generate opaque enums

    Forward declared structs now generate opaque enums

    @emilio : I checked the test outputs again, and it seems that these changes are affecting struct definitions as well. Hence, I have not committed the test changes yet. Fixes #62

    opened by nikhilshagri 25
  • Bindgen produces incorrect bindings to functions with 80-bit long doubles (f80)

    Bindgen produces incorrect bindings to functions with 80-bit long doubles (f80)

    Input C

    // float_to_ld.h
    long double float_to_ld(float f);
    
    // float_to_ld.c
    void test1(void);
    
    long double float_to_ld(float f) {
        return f;
    }
    
    int main() {
        test1();
        return 0;
    }
    

    Bindgen Invocation

    bindgen float_to_ld.h

    Actual Results

    extern "C" {
        pub fn float_to_ld(f: f32) -> u128;
    }
    
    #[no_mangle]
    extern "C" fn test1() {
        let mut buf = [0; 10];
        for (i, x) in buf.iter_mut().enumerate() {
            *x ^= unsafe {
                float_to_ld(i as f32)
            };
        }
        println!("{buf:X?}");
    }
    
    [7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824]
    

    This code fills up and overflows the x87 floating point stack, which doesn't crash the application but results in the stack containing nonsense values rather than the values 8.0, 9.0 expected. (This can be observed with gdb -ex start -ex 'layout asm' -ex 'tui reg float' float_to_ld.) Also the return values in the buffer are not the actual return values of the function as the wrong registers are being used.

    As a more minor annoyance, even if the functions aren't used, rustc emits the warning note: 128-bit integers don't currently have a known stable ABI.

    Expected Results

    Either no bindings should be generated, or inline wrapper functions using inline assembly should be generated which correctly implement the calling convention. Given that Rust has no support for f80, simply omitting the bindings seems like the most pragmatic solution.

    opened by GKFX 0
  • use of VOID typedef results in bindings that return c_void

    use of VOID typedef results in bindings that return c_void

    Input C/C++ Header

    void this_api_returns_nothing(void);
    
    typedef void VOID;
    
    VOID this_api_also_returns_nothing(VOID);
    
    

    Bindgen Invocation

    bindgen::Builder::default()
        .header("input.h")
        .generate()
        .unwrap()
    

    Actual Results

    /* automatically generated by rust-bindgen 0.63.0 */
    
    extern "C" {
        pub fn this_api_returns_nothing();
    }
    pub type VOID = ::std::os::raw::c_void;
    extern "C" {
        pub fn this_api_also_returns_nothing() -> VOID;
    }
    
    
    
    ### Expected Results
    extern "C" {
        pub fn this_api_returns_nothing();
    }
    
    extern "C" {
        pub fn this_api_also_returns_nothing();
    }
    
    Basically the codebase has a typedef for VOID which it uses instead of void..  This results in functions that return c_void which is only intended for pointers.  Any ideas on how to solve?
    opened by AdamGlass 1
  • ty: Deal with using shadow types.

    ty: Deal with using shadow types.

    Bindgen will fail to detect the size_t typedef if it comes from a using declaration, because we'd try to to look at the canonical type.

    This is the root cause of https://bugzilla.mozilla.org/show_bug.cgi?id=1795899, an https://bugzilla.mozilla.org/show_bug.cgi?id=1795899#c30 is the reduced test-case.

    This patch requires an llvm patch to expose the shadow declarations, which I'll submit upstream. This also shows some other progressions as well.

    opened by emilio 0
  • Support complex macros.

    Support complex macros.

    This supersedes https://github.com/rust-lang/rust-bindgen/pull/2268 which aimed to support casts in macros.

    The cmacro crate I developed over the last months allows parsing casts in variable-like macros and even more complex macros, such as function-like macros and nested macros.

    Macro parsing has been split from Var into a separate MacroDef type, since macros need to be parsed last. Variables can be evaluated at parse time, macros on the other hand can only be fully evaluated after all types, variables, functions and other macros have been parsed. This allows getting the correct final value and is needed for parsing nested macros.

    opened by reitermarkus 0
Owner
The Rust Programming Language
The Rust Programming Language
Rust-ffi-guide - A guide for doing FFI using Rust

Using unsafe for Fun and Profit A guide to traversing the FFI boundary between Rust and other languages. A rendered version is available here. This gu

Michael Bryan 261 Dec 1, 2022
Handy macro to generate C-FFI bindings to Rust for Haskell

hs-bindgen Handy macro to generate C-FFI bindings to Rust for Haskell. This library intended to work best in a project configured by cargo-cabal. N.B.

Yvan Sraka 32 Feb 16, 2023
A cross-platform crate with FFI bindings to allow for complex vehicle ECU diagnostics.

ecu_diagnostics A cross-platform crate with FFI bindings to allow for complex vehicle ECU diagnostics. IMPORTANT Currently this crate is not 100% read

Ashcon Mohseninia 80 Dec 24, 2022
Rust Attribute-Based Encryption library rabe's C FFI binding , support CP-ABE and KP-ABE encrypt and decrypt, submodule of Rabe.Core c# library.

Rabe-ffi Rust Attribute-Based Encryption library rabe's C FFI binding , support CP-ABE and KP-ABE encrypt and decrypt, submodule of Rabe.Core c# libra

Aya0wind 2 Oct 10, 2022
Rust in Haskell FFI Example

Provides an example for using Rust in Haskell. To use this you'll need cargo, rustc, cabal and GHC installed. To execute the example run the following

Michael Gattozzi 21 Oct 1, 2022
A safe Rust FFI binding for the NVIDIA® Tools Extension SDK (NVTX).

NVIDIA® Tools Extension SDK (NVTX) is a C-based Application Programming Interface (API) for annotating events, code ranges, and resources in your applications. Official documentation for NVIDIA®'s NVTX can be found here.

Spencer Imbleau 78 Jan 2, 2023
Slitter is a C- and Rust-callable slab allocator implemented primarily in Rust, with some C for performance or to avoid unstable Rust features.

Slitter is a less footgunny slab allocator Slitter is a classically structured thread-caching slab allocator that's meant to help write reliable long-

Backtrace Labs 133 Dec 5, 2022
📝 A template for creating WASM + Typescript + Rust workflow libraries.

Create Rust + TypeScript libraries with ease! PR'S WELCOMED! ✨ Inspiration I wanted to create a WebAssembly/Rust library with additional JS features,

Shaoru Ian Huang 25 Dec 24, 2022
A Rust crate for automatically generating C header files from Rust source file.

Please be aware that this crate is no longer actively maintained, please look into the much more feature rich cbindgen instead. rusty-cheddar rusty-ch

Sean Marshallsay 190 Nov 12, 2022
Create a Python project automatically with rust (like create-react-app but for python)

create-python-project Create a Python project automatically with rust (like create-react-app but for python) Installation cargo install create-python-

Dhravya Shah 2 Mar 12, 2022
This tool converts Lua code to TS automatically, including the conversion of common standards to their TS equivalents.

lua-to-ts This tool converts Lua code to TS automatically, including the conversion of common standards to their TS equivalents. Code that fails to be

Dion 11 Nov 21, 2022
Rust bindings for writing safe and fast native Node.js modules.

Rust bindings for writing safe and fast native Node.js modules. Getting started Once you have the platform dependencies installed, getting started is

The Neon Project 7k Jan 4, 2023
Objective-C Runtime bindings and wrapper for Rust.

Objective-C Runtime bindings and wrapper for Rust. Documentation: http://ssheldon.github.io/rust-objc/objc/ Crate: https://crates.io/crates/objc Messa

Steven Sheldon 336 Jan 2, 2023
WASM bindings for React - enables you to write and use React components in Rust

This library enables you to write and use React components in Rust, which then can be exported to JS to be reused or rendered.

Yichuan Shen 55 Dec 24, 2022
Rust based WASM/JS bindings for ur-rust

ur-wasm-js WASM/JS bindings for the ur-rust rust library Getting started Installation Either build the library yourself with wasm-pack or install for

Lightning Digital Entertainment 5 Feb 28, 2024
A project for generating C bindings from Rust code

cbindgen   Read the full user docs here! cbindgen creates C/C++11 headers for Rust libraries which expose a public C API. While you could do this by h

Ryan Hunt 1.7k Jan 3, 2023
Rust-JDBC bindings

jdbc A Rust library that allows you to use JDBC and JDBC drivers. Usage First, add the following to your Cargo.toml: [dependencies] jdbc = "0.1" Next,

Aurora 18 Feb 9, 2022
Lua 5.3 bindings for Rust

rust-lua53 Aims to be complete Rust bindings for Lua 5.3 and beyond. Currently, master is tracking Lua 5.3.3. Requires a Unix-like environment. On Win

J.C. Moyer 150 Dec 14, 2022
Safe Rust bindings to Lua 5.1

rust-lua Copyright 2014 Lily Ballard Description This is a set of Rust bindings to Lua 5.1. The goal is to provide a (relatively) safe interface to Lu

Lily Ballard 124 Jan 5, 2023