microsoft / cppwinrt

C++/WinRT
MIT License
1.64k stars 238 forks source link

Add `capture` support for unconventional result types #1301

Closed kennykerr closed 1 year ago

kennykerr commented 1 year ago

Fixes: #1299

oldnewthing commented 1 year ago

I was originally worried that this might be too permissive. There are some methods that take a REFIID followed by something that isn't the matched output pointer. However, they are exceedingly rare, and the only one that does it at the end of the parameter list that I could find (mind you, I gave up halfway through the D's) is IDebugProperty::EnumMembers, so I concluded that the very low risk wasn't worth the extra protection.

Unit test needs to include the forwarder pattern:

com_ptr<ICapture> f = capture<ICapture>([&](auto riid, auto ppv) { return CreateCapture2(10, riid, ppv); });

This pattern is used to accommodate methods that don't put the riid/ppv as the last two parameters.

HRESULT WeirdMethod(REFIID riid, char const* interloper, IUnknown** result, int straggler);

e.capture<IUnknown>(WeirdMethod, [](auto interloper, auto straggler, auto riid, auto result) { return WeirdMethod(riid, interloper, result, straggler); }, "interloper", 10);