windows-rs icon indicating copy to clipboard operation
windows-rs copied to clipboard

Support COM-like interfaces that don't inherit from IUnknown

Open kennykerr opened this issue 4 years ago • 3 comments

Need a way to deal with COM-like interfaces such as ID3D11FunctionParameterReflection that don't inherit from IUnknown.

kennykerr avatar Jan 27 '21 22:01 kennykerr

I ran into this recently when trying to use the XAudio2 APIs. Specifically, the IXAudio2Voice interfaces and their callback interfaces don't inherit from IUnknown either. Maybe useful as another test case for this issue.

mattrudder avatar May 30 '21 17:05 mattrudder

Thanks Matt, will keep that in mind.

kennykerr avatar Jun 08 '21 19:06 kennykerr

Just to clarify that this issue is about interfaces that look like COM interfaces but don't inherit from IUnknown and are thus not COM interfaces at all. They're basically just a vtable without the grounding that IUnknown provides for lifetime and polymorphism. They're somewhat rare and mostly seem to be used for callbacks, basically a collection of callback functions.

Ideally you'd be able to implement such an interface with the implement macro as you can actual COM interfaces, but the implement macro will need some work to know that such interfaces don't need all the COM plumbing and that something outside of COM will control the interface's lifetime.

Such interface declarations in the windows crate also need to not have a Drop implementation since that currently calls Release on IUnknown and such types should not implement the Interface trait, which requires an IUnknown vtable.

kennykerr avatar Jul 13 '22 17:07 kennykerr

I also ran into this with the IDebugFAEntryTags interface which doesn't derive from IUnknown.

In my case, I just need to use an instance of the interface which I'm given as a parameter, not actually implement it myself. I think wrapping the type in ManuallyDrop would prevent windows-rs/Rust from trying to call IUnknown::Release from Drop::drop ie:

fn FuncFoo(tags: ManuallyDrop<IDebugFAEntryTags>) { ... }

Am I way off base there?

wesleywiser avatar Sep 09 '22 23:09 wesleywiser

Yes, the ManuallyDrop would suppress the Release call but it wouldn't prevent the vtable from including, or expecting, the three IUnknown members. So if you're using the interface macro to define the interface you'd still end up with the incorrect function pointer offsets. I'll try to find some time this week to get this working.

kennykerr avatar Sep 10 '22 12:09 kennykerr