Trait uniffi::HandleAlloc

pub unsafe trait HandleAlloc<UT>: Send + Sync {
    // Required methods
    fn new_handle(value: Arc<Self>) -> Handle;
    fn clone_handle(handle: Handle) -> Handle;
    fn consume_handle(handle: Handle) -> Arc<Self>;

    // Provided method
    fn get_arc(handle: Handle) -> Arc<Self> { ... }
}
Expand description

Manage handles for Arc<Self> instances

Handles are used to manage objects that are passed across the FFI. They general usage is:

  • Rust creates an Arc<>
  • Rust uses new_handle to create a handle that represents the Arc reference
  • Rust passes the handle to the foreign code as a u64
  • The foreign code passes the handle back to Rust to refer to the object:
    • Handle are usually passed as borrowed values. When an FFI function inputs a handle as an argument, the foreign code simply passes a copy of the u64 to Rust, which calls get_arc to get a new Arc<> clone for it.
    • Handles are returned as owned values. When an FFI function returns a handle, the foreign code either stops using the handle after returning it or calls clone_handle and returns the clone.
  • Eventually the foreign code may destroy their handle by passing it into a “free” FFI function. This functions input an owned handle and consume it.

The foreign code also defines their own handles. These represent foreign objects that are passed to Rust. Using foreign handles is essentially the same as above, but in reverse.

Handles must always be Send and the objects they reference must always be Sync. This means that it must be safe to send handles to other threads and use them there.

Note: this only needs to be derived for unsized types, there’s a blanket impl for T: Sized.

Safety

All traits are unsafe (implementing it requires unsafe impl) because we can’t guarantee that it’s safe to pass your type out to foreign-language code and back again. Buggy implementations of this trait might violate some assumptions made by the generated code, or might not match with the corresponding code in the generated foreign-language bindings. These traits should not be used directly, only in generated code, and the generated code should have fixture tests to test that everything works correctly together. &T using the Arc.

Required Methods§

fn new_handle(value: Arc<Self>) -> Handle

Create a new handle for an Arc value

Use this to lower an Arc into a handle value before passing it across the FFI. The newly-created handle will have reference count = 1.

fn clone_handle(handle: Handle) -> Handle

Clone a handle

This creates a new handle from an existing one. It’s used when the foreign code wants to pass back an owned handle and still keep a copy for themselves.

fn consume_handle(handle: Handle) -> Arc<Self>

Consume a handle, getting back the initial Arc<>

Provided Methods§

fn get_arc(handle: Handle) -> Arc<Self>

Get a clone of the Arc<> using a “borrowed” handle.

Take care that the handle can not be destroyed between when it’s passed and when get_arc() is called. #1797 is a cautionary tale.

Implementors§

§

impl<T, UT> HandleAlloc<UT> for Twhere T: Send + Sync,