Reusing your C++ code in rust (embedded)
But why ?
So you have some working code in c++ and you'd like to reuse in rust (libraries, hal,...) ?
That's not uncommon, that code works and you may not want to spend times re-writing it for no gain (and also avoid double maintenance)
Option 1 : Bindgen
Bindgen is nice enough, give it a .h, it will generate automatically the rust bindings for it.
But it comes with some annoying limitations :
- It does not support virtual methods
- The parameters are C/C++ types, not rust types, it feels awkard to use them.
Example : func(usize , void *) vs func( data : &[u8])
- The generated functions are unsafe
Option 2 ; Dual adaptation layer
The idea here is to create :
1- A first shim layer that exports the C++ API as C api + a void *this parameter.
2- Run bindgen on this shim, that will create unsafe rust with c++ parameters.
3- Create proper rust code that is using that unsafe rust code
The actual API is the one from the "proper code".
It is *not* unsafe, it is using native rust types.
It is a bit of a pain to write the glue code, but it's very straightforward.
A sample example available here : https://github.com/mean00/lnArduino/blob/master/rust/rnArduino/src/rn_i2c.rs
c++ I2C -> shim -> rn_i2c_c.rs (bindgen) -> rnI2C.rs (proper)
So you have some working code in c++ and you'd like to reuse in rust (libraries, hal,...) ?
That's not uncommon, that code works and you may not want to spend times re-writing it for no gain (and also avoid double maintenance)
Option 1 : Bindgen
Bindgen is nice enough, give it a .h, it will generate automatically the rust bindings for it.
But it comes with some annoying limitations :
- It does not support virtual methods
- The parameters are C/C++ types, not rust types, it feels awkard to use them.
Example : func(usize , void *) vs func( data : &[u8])
- The generated functions are unsafe
Option 2 ; Dual adaptation layer
The idea here is to create :
1- A first shim layer that exports the C++ API as C api + a void *this parameter.
2- Run bindgen on this shim, that will create unsafe rust with c++ parameters.
3- Create proper rust code that is using that unsafe rust code
The actual API is the one from the "proper code".
It is *not* unsafe, it is using native rust types.
It is a bit of a pain to write the glue code, but it's very straightforward.
A sample example available here : https://github.com/mean00/lnArduino/blob/master/rust/rnArduino/src/rn_i2c.rs
c++ I2C -> shim -> rn_i2c_c.rs (bindgen) -> rnI2C.rs (proper)
Comments
Post a Comment