Rantanen / intercom

Object based cross-language FFI for Rust
MIT License
63 stars 7 forks source link

Need a way to handle type systems in `ComItf`/`ComRc` #81

Closed Rantanen closed 5 years ago

Rantanen commented 5 years ago

Currently the pointer wrappers: ComItf and ComRc have Rust traits as generic parameters but on the low level they carry COM pointers.

This worked while we had one-to-one mapping between Rust traits and COM interfaces. However now that we have multiple type systems our ComItf might need to point to one of the two COM interfaces. This becomes problematic especially when handling ComItf/ComRc as return values/parameters.

Logically when a ComRc is returned from a Rust method, the the caller would expect a COM interface pointer to the Automation interface of the returned object if the method they received it from uses Automation type system - on the other hand a C++ caller using the Raw type system would expect to receive a Raw type system interface pointer.

This means that the ComItf we return from Rust needs to be a fat type which stores the object as is and is able to resolve either the automation type system or raw type system when we are converting the Rust return value into raw COM return value in the tyhandlers.

Rantanen commented 5 years ago

Currently ComItf is a new type around RawComPtr. It needs to become a fat type that can hold either type interface pointer or both.

struct ComItf<T> {
    automation_ptr: RawComPtr,
    raw_ptr: RawComPtr,
    phantom_data: PhantomData<T>,
}

Either of these pointers can be null if the type system is unavailable.

ComRc<T> should be a simple wrapper around ComItf that just does ref counting on create/drop so the above change should affect that as well.

The big difference this causes for the actual ComItf trait impls is that the user traits need to implement calls through both Raw and Automation type systems. Currently the traits are implemented only through a predefined type system (which also won't work if the COM pointer given by the caller is of the other type system.

When Raw type system interface receives a COM pointer for an interface, the ComItf constructed will set the automation pointer to null, which will ensure that any COM call performed on the ComItf from Rust will use the raw COM pointer.

Things like CreateInstance etc. will fill only the correct pointer type (Automation).

Rantanen commented 5 years ago

Fixed in #80