Crate mcom

Source
Expand description

MaulingMonkey’s COM interfaces/types/wrappers.

§Smart Pointers

TypeSend
Sync
LazyEagerWindowsPartitionDescription
Rc❌ noN/AN/A2000+anyYour basic, super vanilla, apartment & thread-local COM pointer.
Git✔️ yes✔️ yes❌ no2000+anyIGlobalInterfaceTable-based COM pointer.
Agile✔️ yes✔️ yes✔️ yes⚠️ 8.1+gamesIAgileReference-based COM pointer.

COM interfaces have complicated thread safety guarantees - when they have thread safety guarantees at all. While some of those guarantees can be expressed through the type system (e.g. many/most WinRT interfaces are guaranteed agile), many of the more subtle ones can only be effectively expressed at runtime.

For example, an interface pointer to a given COM object might be usable on other threads of a MTA apartment, but not on STA threads. While we could have some kind of MTA token type only constructable on MTA threads, and require that for accessing the smart pointer, such a token would likely need to be retrieved at runtime anyways - and just add more steps an extra complexity.

Since WinRT’s free-threaded agile guarantees are the only ones that really line up well with WinRT’s type system, and WinRT’s rich metadata calls for WinRT-specific crates that can tackle that (e.g. winrt), that leaves this crate to tackle the messier runtime-enforced thread safety of more vanilla COM.

All these smart pointers assume the COM interface implements IUnknown. It’s worth noting that some “COM” interfaces like ID3D12FunctionReflection do not implement IUnknown, and cannot be held in any of these COM smart pointers as a result.

LegendDescription
LazyErrors out when converting Agile/Git 🠆 Rc if the COM object is being being used in another COM Apartment, unless it is safe to do so. This is usable even for unmarshalable types (such as Direct3D interfaces) if you stay within the appropriate COM apartment and they implement IUnknown.
EagerErrors out when converting Rc 🠆 Agile/Git if the COM object isn’t portable between COM Apartments (e.g. not 100% thread safe) and cannot be wrapped in a marshaling layer that would make it portable.
WindowsWhat version of windows is required for this interface. Most APIs are marked 2000+ because that’s what microsoft.com says, but likely predate Windows 2000.
PartitionWINAPI_PARTITION_* references, as selected by winapi-family-* features. Allows hiding e.g. CoCreateInstance from UWP apps that must use CoCreateInstanceFromApp instead. See winapifamily.h for more details.

Modules§

Documentation
Crate Features, Known Soundness Holes & Undefined Behavior Bait
errors
MethodHResult
init
Wrappers around CoInitializeEx etc. for initializing COM.

Structs§

Agile
A Send+Sync, IAgileReference-held interface pointer.
Git
A Send+Sync, IGlobalInterfaceTable-held interface pointer.
Rc
A !Send+!Sync basic reference counting smart pointer residing within the current COM apartment.