Created
February 9, 2023 16:45
-
-
Save stevedoyle/39451d0e10a5e62a6db85829b97c2d83 to your computer and use it in GitHub Desktop.
Rust code for calling C APIs that use opaque pointers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(non_upper_case_globals)] | |
#![allow(non_camel_case_types)] | |
#![allow(non_snake_case)] | |
include!("../bindings.rs"); | |
fn main() { | |
unsafe { | |
let size = fooGetCtxSize(); | |
println!("Ctx Size: {}", size); | |
// Need to allocate memory to hold the context. | |
// Can't use the FooState type from bindings.rs since this is an opaque | |
// type on the interface and it maps to a zero sized structure. Just to | |
// prove this ... | |
let fooStateSize = std::mem::size_of::<FooState>(); | |
println!("size_of(FooState) = {}", fooStateSize); | |
// Approach #1 - Using an uninitialized vector | |
// Lets start out with a vector with enough capacity to hold the context | |
let mut ctxbuf: Vec<u8> = Vec::with_capacity(size as usize); | |
// Then get a pointer to the spare capacity buffer and cast it to a | |
// pointer of the FooState type. | |
let state: *mut FooState = ctxbuf.spare_capacity_mut().as_mut_ptr().cast(); | |
let status = fooInitCtx(state); | |
assert_eq!(0, status); | |
let status = fooDoSomething(state, 5); | |
assert_eq!(0, status); | |
// Approach #2 - Using an initialized vector | |
// Lets start out with a Vec<u8> of the right size and filled with zeros | |
// and convert it into a boxed slice ... | |
let mut buf = vec![0u8; size as usize].into_boxed_slice(); | |
// ... which can then provide a pointer to the buffer memory which can | |
// be cast to a pointer of the correct type. | |
let state = buf.as_mut_ptr() as *mut FooState; | |
let status = fooInitCtx(state); | |
assert_eq!(0, status); | |
let status = fooDoSomething(state, 5); | |
assert_eq!(0, status); | |
} | |
println!("Hello, world!"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment