For example, if we have normal rust function:
pub fn kork(zork: u64) -> bool
We'd generate this Rust wrapper library code:
#[no_mangle]
pub extern "C" fn kork_extern(zork: u64) -> bool {
inner_lib::kork(zork)
}
When structs and enums get involved, a twist: C should only see sized, opaque structs. Let's assume that C can know the size of Rust structs via preprocessor #define's handed in via command line.
Example:
struct MyRustStruct {
// Arbitrary fields here
}
pub fn bork(splork_raw: MyRustStruct) -> MyRustStruct
Rust wrapper:
#[repr(C)]
pub struct MyRustStruct_extern([u8; std::mem::size_of::<MyStruct>()]);
#[no_mangle]
pub extern "C" fn bork_extern(
splork_raw: *const MyRustStruct_extern,
result_raw: *mut MyRustStruct_extern) {
let splork_ref: &MyRustStruct = &*(splork_raw as *const MyRustStruct);
let result_struct = bork(*splork_ref);
(result_raw as *mut MyRustStruct).write(result_struct);
}
C header:
#ifndef RUST_WRAPPER_H
#define RUST_WRAPPER_H
#pragma pack(1)
#include <stdint.h>
// MyRustStruct_extern_SIZE must be handed in via command line
#ifndef MyRustStruct_extern_SIZE
#error "MyRustStruct_extern_SIZE must be defined"
#endif
typedef struct {
uint8_t data[MyRustStruct_extern_SIZE];
} MyRustStruct_extern;
void bork_extern(
MyRustStruct_extern* splork_raw,
MyRustStruct_extern* result_raw);
#endif /* RUST_WRAPPER_H */
Another example:
pub fn bloop(path: &Path) -> Vec<u8>
Rust wrapper code:
#[repr(C)]
pub struct Path_extern([u8; std::mem::size_of::<Path>()]);
#[repr(C)]
pub struct VecU8_extern([u8; std::mem::size_of::<Vec<u8>>()]);
#[no_mangle]
pub extern "C" fn bloop_extern(
path_raw: *const Path_extern,
result_raw: *mut VecU8_extern) {
let path_ref: &Path = &*(path_raw as *const Path);
let result_struct = bloop(*path_ref);
let result_ptr: *mut VecU8_extern = result_raw as *mut VecU8_extern;
result_ptr.write(result_struct);
}
C header:
#ifndef RUST_WRAPPER_H
#define RUST_WRAPPER_H
#pragma pack(1)
#include <stdint.h>
// Path_extern_SIZE must be handed in via command line
#ifndef Path_extern_SIZE
#error "Path_extern_SIZE must be defined"
#endif
typedef struct {
uint8_t data[Path_extern_SIZE];
} Path_extern;
// VecU8_extern_SIZE must be handed in via command line
#ifndef VecU8_extern_SIZE
#error "VecU8_extern_SIZE must be defined"
#endif
typedef struct {
uint8_t data[VecU8_extern_SIZE];
} VecU8_extern;
void bloop_extern(
Path_extern* splork_raw,
VecU8_extern* result_raw);
#endif /* RUST_WRAPPER_H */