SlideShare a Scribd company logo
1 of 18
Download to read offline
Interface Oxidation
Razvan Rotari
FFI
● Rust FFI uses C ABI
● Rust ABI is not standardized
● C++ ABI is not standardized
C -> Rust
C
int oxidize(int i);
int ret = oxidize(42);
Rust
#[no_mangle]
pub extern "C" fn oxidize(i: i32) -> i32 {
println!("Oxidize {}", i);
i+1
}
How to automate this?
How crates work
● Package manager concept (cargo)
● A crate is the way to package a module
● Can generate executable and libraries
● Can contain subfolders
● Handles the dependencies using cargo
● Compile-time scripting
ROOT
src
lib.rs # entry point for libs
main.rs # entry point for exe
Cargo.toml
Build.rs - run at compile-time
CBindgen
● Generates C or C++ headers that wraps the Rust code
● Functions need to be annotated with #[no_mangle]
● Types need to be annotated with #[repr(C)]
● Does not handle all cases
● Can be run standalone or at compile time
CBindgen
C
typedef struct TestStruct {
int32_t age;
} TestStruct;
typedef enum TestEnum_Tag{
TestEnum_First,
TestEnum_Second,
TestEnum_Empty,
} TestEnum_Tag;
typedef struct TestEnum{
TestEnum_Tag tag;
union {
struct{
int32_t first;
};
struct { float second; }; };
} TestEnum;
Rust
#[repr(C)]
pub struct TestStruct{
age: i32,
}
#[repr(C)]
pub enum TestEnum{
First(i32),
Second(f32),
Empty,
}
Rust -> C
C
int call_me(int i);
Rust
extern “C” {
fn call_me(i:i32) -> i32;
}
fn main() {
let ret = call_me(42);
}
Bindgen
● Parses the C headers and generates Rust wrappers.
● Run at compile time or as standalone application.
● Convention is to make a new crate with the suffix -sys for each lib. Ex. openssl-sys
● Recommended to create a C header in the crate as the starting point.
● Can handle C++ to some extent.
● Define macros are converted in constants
● Function macros are ignored
● Templates are ignored
Bindgen
lib.rs
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
include!("bindings.rs");
build.rs
let bindings = bindgen::Builder::default()
.header("wrapper.hpp")
.clang_arg("-I../../src")
.generate();
bindings.write_to_file("bindings.rs");
println!("cargo:rerun-if-changed=wrapper.hpp");
Error handling
● Safe Rust does not have NULL, instead uses Optional<T>.
● Rust has pointers, but operation needs to be done in unsafe code.
● For error handling Rust uses Result<T,E>, where E is the error type.
● Rust has something similar to exceptions called panic. Are used only in
specific cases for fatal errors.
● C++ uses exceptions and return codes.
● Panics and exceptions are not compatible.
● Exceptions MUST NOT cross the FFI boundary
● Use a common logging system. Most rust logging crates provide a way to
write custom adaptors.
Error handling - Exceptions to Result
1. Parse C++ headers using `clang -Xclang -fsyntax-only –ast-dump=json`
2. For each possible return type create a variant that contains the return type
and the exception in C
3. In Rust for each variant write conversion functions to Result<T,E>
4. For each function generate a wrapper that catches the exception and
converts it to the variant in C
5. Generate Rust bindings only for the wrappers
Error handling - Result to Exceptions
1. Parse Rust code using `syn` crate
2. For each possible Result used generate in Rust a variant that can be created
from a Result
3. For each function generate in Rust a wrapper that calls the functions and
converts the result to the variant.
4. For each wrapper generate in C++ another wrapper that converts the variant
to an exception
Callbacks
● Hard to wrap.
● Easy to throw exceptions in the middle of that code.
● Either write them with care or create a wrapper that handles all the error
handling.
● Thread safety
● Use the ‘user data’ pattern when posibile.
Issues
● Different C/C++ compilers use different underlying types for common types.
● char might be signed or unsigned, 1 byte or 4 bytes.
● Use fixed sized type when possible.
● Calling convention might be different.
● Make sure the generated code uses the same compiler flags as the normal
one
● Rust might use different allocator then C code, so freeing needs to be
handled in the same code base.
● Rust strings are UTF-8 and are not NULL terminated. Conversions need to be
done using the CString/&cstr classes.
Good news
● Gdb and rr can works with both languages at the same time.
● Backtraces will make sense.
● ‘Go-to definition’ feature will work in your IDE.
Questions?
● https://doc.rust-lang.org/nomicon/ffi.html
● https://docs.rs/syn/latest/syn/
● https://github.com/eqrion/cbindgen/tree/master
● https://rust-lang.github.io/rust-bindgen/
● https://nrc.github.io/error-docs

More Related Content

Similar to Interface Oxidation

Lightweight Virtualization with Linux Containers and Docker I YaC 2013
Lightweight Virtualization with Linux Containers and Docker I YaC 2013Lightweight Virtualization with Linux Containers and Docker I YaC 2013
Lightweight Virtualization with Linux Containers and Docker I YaC 2013
Docker, Inc.
 
Unmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/InvokeUnmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/Invoke
Dmitri Nesteruk
 

Similar to Interface Oxidation (20)

Lightweight Virtualization with Linux Containers and Docker I YaC 2013
Lightweight Virtualization with Linux Containers and Docker I YaC 2013Lightweight Virtualization with Linux Containers and Docker I YaC 2013
Lightweight Virtualization with Linux Containers and Docker I YaC 2013
 
Not Your Fathers C - C Application Development In 2016
Not Your Fathers C - C Application Development In 2016Not Your Fathers C - C Application Development In 2016
Not Your Fathers C - C Application Development In 2016
 
Robust C++ Task Systems Through Compile-time Checks
Robust C++ Task Systems Through Compile-time ChecksRobust C++ Task Systems Through Compile-time Checks
Robust C++ Task Systems Through Compile-time Checks
 
C tutorial
C tutorialC tutorial
C tutorial
 
Switch case and looping
Switch case and loopingSwitch case and looping
Switch case and looping
 
New c sharp4_features_part_vi
New c sharp4_features_part_viNew c sharp4_features_part_vi
New c sharp4_features_part_vi
 
Dart the Better JavaScript
Dart the Better JavaScriptDart the Better JavaScript
Dart the Better JavaScript
 
DConf 2016: Keynote by Walter Bright
DConf 2016: Keynote by Walter Bright DConf 2016: Keynote by Walter Bright
DConf 2016: Keynote by Walter Bright
 
88 c programs 15184
88 c programs 1518488 c programs 15184
88 c programs 15184
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 
Advanced Linux Game Programming
Advanced Linux Game ProgrammingAdvanced Linux Game Programming
Advanced Linux Game Programming
 
AOT-compilation of JavaScript with V8
AOT-compilation of JavaScript with V8AOT-compilation of JavaScript with V8
AOT-compilation of JavaScript with V8
 
Metasepi team meeting #7: Snatch application on tiny OS
Metasepi team meeting #7: Snatch application on tiny OSMetasepi team meeting #7: Snatch application on tiny OS
Metasepi team meeting #7: Snatch application on tiny OS
 
Unmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/InvokeUnmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/Invoke
 
How to control physical devices with mruby
How to control physical devices with mrubyHow to control physical devices with mruby
How to control physical devices with mruby
 
(4) cpp automatic arrays_pointers_c-strings
(4) cpp automatic arrays_pointers_c-strings(4) cpp automatic arrays_pointers_c-strings
(4) cpp automatic arrays_pointers_c-strings
 
Crystal internals (part 1)
Crystal internals (part 1)Crystal internals (part 1)
Crystal internals (part 1)
 
Crystal internals (part 1)
Crystal internals (part 1)Crystal internals (part 1)
Crystal internals (part 1)
 
Crystal internals (part 1)
Crystal internals (part 1)Crystal internals (part 1)
Crystal internals (part 1)
 
C for Java programmers (part 1)
C for Java programmers (part 1)C for Java programmers (part 1)
C for Java programmers (part 1)
 

More from Ovidiu Farauanu

More from Ovidiu Farauanu (10)

Back in Business with C++
Back in Business with C++Back in Business with C++
Back in Business with C++
 
Optimization of the build times using Conan
Optimization of the build times using ConanOptimization of the build times using Conan
Optimization of the build times using Conan
 
Bind me if you can
Bind me if you canBind me if you can
Bind me if you can
 
Distributed Cache, bridging C++ to new technologies (Hazelcast)
Distributed Cache, bridging C++ to new technologies (Hazelcast)Distributed Cache, bridging C++ to new technologies (Hazelcast)
Distributed Cache, bridging C++ to new technologies (Hazelcast)
 
Monadic Computations in C++14
Monadic Computations in C++14Monadic Computations in C++14
Monadic Computations in C++14
 
Domain Specific Languages and C++ Code Generation
Domain Specific Languages and C++ Code GenerationDomain Specific Languages and C++ Code Generation
Domain Specific Languages and C++ Code Generation
 
Florentin Picioroaga - C++ by choice
Florentin Picioroaga - C++ by choiceFlorentin Picioroaga - C++ by choice
Florentin Picioroaga - C++ by choice
 
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
 
High Order Function Computations in c++14 (C++ Dev Meetup Iasi)
High Order Function Computations in c++14 (C++ Dev Meetup Iasi)High Order Function Computations in c++14 (C++ Dev Meetup Iasi)
High Order Function Computations in c++14 (C++ Dev Meetup Iasi)
 
Cap'n Proto (C++ Developer Meetup Iasi)
Cap'n Proto (C++ Developer Meetup Iasi)Cap'n Proto (C++ Developer Meetup Iasi)
Cap'n Proto (C++ Developer Meetup Iasi)
 

Recently uploaded

CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 

Recently uploaded (20)

Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 

Interface Oxidation

  • 2. FFI ● Rust FFI uses C ABI ● Rust ABI is not standardized ● C++ ABI is not standardized
  • 3. C -> Rust C int oxidize(int i); int ret = oxidize(42); Rust #[no_mangle] pub extern "C" fn oxidize(i: i32) -> i32 { println!("Oxidize {}", i); i+1 }
  • 5. How crates work ● Package manager concept (cargo) ● A crate is the way to package a module ● Can generate executable and libraries ● Can contain subfolders ● Handles the dependencies using cargo ● Compile-time scripting ROOT src lib.rs # entry point for libs main.rs # entry point for exe Cargo.toml Build.rs - run at compile-time
  • 6. CBindgen ● Generates C or C++ headers that wraps the Rust code ● Functions need to be annotated with #[no_mangle] ● Types need to be annotated with #[repr(C)] ● Does not handle all cases ● Can be run standalone or at compile time
  • 7. CBindgen C typedef struct TestStruct { int32_t age; } TestStruct; typedef enum TestEnum_Tag{ TestEnum_First, TestEnum_Second, TestEnum_Empty, } TestEnum_Tag; typedef struct TestEnum{ TestEnum_Tag tag; union { struct{ int32_t first; }; struct { float second; }; }; } TestEnum; Rust #[repr(C)] pub struct TestStruct{ age: i32, } #[repr(C)] pub enum TestEnum{ First(i32), Second(f32), Empty, }
  • 8. Rust -> C C int call_me(int i); Rust extern “C” { fn call_me(i:i32) -> i32; } fn main() { let ret = call_me(42); }
  • 9. Bindgen ● Parses the C headers and generates Rust wrappers. ● Run at compile time or as standalone application. ● Convention is to make a new crate with the suffix -sys for each lib. Ex. openssl-sys ● Recommended to create a C header in the crate as the starting point. ● Can handle C++ to some extent. ● Define macros are converted in constants ● Function macros are ignored ● Templates are ignored
  • 10. Bindgen lib.rs #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] include!("bindings.rs"); build.rs let bindings = bindgen::Builder::default() .header("wrapper.hpp") .clang_arg("-I../../src") .generate(); bindings.write_to_file("bindings.rs"); println!("cargo:rerun-if-changed=wrapper.hpp");
  • 11. Error handling ● Safe Rust does not have NULL, instead uses Optional<T>. ● Rust has pointers, but operation needs to be done in unsafe code. ● For error handling Rust uses Result<T,E>, where E is the error type. ● Rust has something similar to exceptions called panic. Are used only in specific cases for fatal errors. ● C++ uses exceptions and return codes. ● Panics and exceptions are not compatible. ● Exceptions MUST NOT cross the FFI boundary ● Use a common logging system. Most rust logging crates provide a way to write custom adaptors.
  • 12. Error handling - Exceptions to Result 1. Parse C++ headers using `clang -Xclang -fsyntax-only –ast-dump=json` 2. For each possible return type create a variant that contains the return type and the exception in C 3. In Rust for each variant write conversion functions to Result<T,E> 4. For each function generate a wrapper that catches the exception and converts it to the variant in C 5. Generate Rust bindings only for the wrappers
  • 13. Error handling - Result to Exceptions 1. Parse Rust code using `syn` crate 2. For each possible Result used generate in Rust a variant that can be created from a Result 3. For each function generate in Rust a wrapper that calls the functions and converts the result to the variant. 4. For each wrapper generate in C++ another wrapper that converts the variant to an exception
  • 14. Callbacks ● Hard to wrap. ● Easy to throw exceptions in the middle of that code. ● Either write them with care or create a wrapper that handles all the error handling. ● Thread safety ● Use the ‘user data’ pattern when posibile.
  • 15. Issues ● Different C/C++ compilers use different underlying types for common types. ● char might be signed or unsigned, 1 byte or 4 bytes. ● Use fixed sized type when possible. ● Calling convention might be different. ● Make sure the generated code uses the same compiler flags as the normal one ● Rust might use different allocator then C code, so freeing needs to be handled in the same code base. ● Rust strings are UTF-8 and are not NULL terminated. Conversions need to be done using the CString/&cstr classes.
  • 16. Good news ● Gdb and rr can works with both languages at the same time. ● Backtraces will make sense. ● ‘Go-to definition’ feature will work in your IDE.
  • 18. ● https://doc.rust-lang.org/nomicon/ffi.html ● https://docs.rs/syn/latest/syn/ ● https://github.com/eqrion/cbindgen/tree/master ● https://rust-lang.github.io/rust-bindgen/ ● https://nrc.github.io/error-docs