Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Receiving COM interface pointers as parameters #99

Open
@Rantanen

Description

@Rantanen

The following use case:

// C++ COM client

CComPtr<ILogic> logic = ...;
CComPtr<IData> data = ...;
logic.DoLogic(data);  // C++ holds reference count. This is essentially "a borrow".
// Rust COM server

impl ILogic for CoLogic {
    fn do_logic(&self, data: *mut c_void) {
        // Safety requirements for InterfacePtr::new.
        // - ptr is valid pointer of 'T'
        // - ptr must live as long as InterfacePtr
        let ptr = unsafe {
            InterfacePtr<IData>::new(data);
        }

        // Rust wants ownership and turns the 'ptr' into a Rc.

        // This should increment reference count (but doesn't currently).
        let rc = InterfaceRc::new(data);

        // This would increment reference count, but is not implemented for InterfacePtr.
        let rc = InterfacePtr::get_interface<IOtherData>(ptr);
    }
}

So couple of needs:

  • Provide unsafe "InterfacePtr into InterfaceRc without add_ref" method.
    • Currently InterfaceRc::new does this, but isn't marked as unsafe, thus leading to easy double-release, if the user forgets to manually call add_ref.
  • Provide safe "InterfacePtr into InterfaceRc with add_ref" method.
    • As long as InterfaceRc does add_ref, there should be no other safety concerns, assuming the pointer itself is valid (which InterfacePtr seems to imply based on the safety requirements on its new method).
  • Implement get_interface on InterfacePtr.
    • Currently the user must turn any pointer into Rc type just to call get_interface

Maybe look into implementing a lifetime scoped variant of InterfacePtr:

#[repr(transparent)]
ScopedInterfacePtr<'a, TInterface> {
    ptr: *mut c_void,
    phantom: &'a PhantomData<TInterface>
}

This should prevent accidentally moving the pointer somewhere that would outlive the function call.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions