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
Description
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
intoInterfaceRc
withoutadd_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 calladd_ref
.
- Currently
- Provide safe "
InterfacePtr
intoInterfaceRc
withadd_ref
" method.- As long as
InterfaceRc
doesadd_ref
, there should be no other safety concerns, assuming the pointer itself is valid (whichInterfacePtr
seems to imply based on the safety requirements on itsnew
method).
- As long as
- Implement
get_interface
onInterfacePtr
.- Currently the user must turn any pointer into
Rc
type just to callget_interface
- Currently the user must turn any pointer into
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.