Owned and borrowed FFI wrapper types

I'm writing a wrapper for a C library. The library has an opaque type that can either be created and Dropped from Rust side, and also can be "borrowed" in Rust from object created on the C side (Rust is not supposed to dealloc the object, so Drop is inappropriate).

What's the best way to express this in Rust?


(I'm using the C library's custom init and deinit functions, so apart from Rust wrapper type nothing is allocated by Rust, so there's no problem of mixing of allocators)

Ideally I'd like to write impl for both owned and borrowed wrappers once, and have both types compatible.

struct Foo {
    handle: *mut ffi::Foo; // Should I use &'a mut ffi::Foo? Cow?
}

impl Drop for Foo {
   fn drop(&mut self) {
       unsafe { ffi::deinit(self.handle); } // Not appropriate for the "borrowed" handle!
   }
}

impl Foo {
   pub fn new() -> Self {…}
   unsafe pub fn borrowed_from_handle(handle: *mut ffi::Foo) -> ??? {…}
}
1 Like

After a bunch of experimentation in rust-openssl, I've ended up with foreign_types - Rust

6 Likes

Thank you @sfackler, that's exactly what I needed!