Generate safe COM output pointer ABI - #1831
Merged
Merged
Conversation
Project canonical IID/ComOutPtr pairs as out void* and provide ComOutPtr.FromManaged for managed COM implementers. Preserve friendly generic overloads and cover source-generated, built-in, and WinRT marshalling configurations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Project the returned IDispatch pointer through built-in COM and release the caller-owned native reference. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Build unofficial VS-feed previews without strong-name identities when package signing is disabled, avoiding invalid delay-signed assemblies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The signing plugin rejects assemblies that intentionally have no public key, so omit it only when publishing unsigned VS-feed preview packages. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the pull request focused on the COM output pointer ABI now that preview validation is complete. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Jevan Saks (jevansaks)
marked this pull request as ready for review
October 1, 2026 06:10
Sergio Pedri (Sergio0694)
approved these changes
Oct 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
IID + [ComOutPtr] void**interface parameters as implementation-safeout void*Windows.Win32.ComOutPtr.FromManagedto return the exact requested interface with caller-owned COM reference semanticsout Tfriendly overloads and adaptive COM/WinRT projectionUseIntPtrForComOutPointersbehaviorIClassFactoryimplementations across source-generated COM, built-in COM, and auto-WinRT enabled/disabled configurationsFixes #1827
Rationale and compatibility
A native COM method with an
IID + ppvparameter pair promises more than simply returning a COM pointer. On success,ppvmust point at the exact interface identified by the IID, with that interface's vtable layout and a caller-owned reference. The native caller immediately interprets the returned pointer according to the requested interface and invokes its vtable slots.The current managed
out objectprojection cannot guarantee that contract for implementations. The COM source generator recognizesIidParameterIndex, but it does not make the sibling IID value available to the custom marshaller for the[ComOutPtr]parameter. The marshaller can obtain a COM pointer for the managed object, but it cannot performQueryInterfacefor the IID the caller actually requested. The pointer may therefore representIUnknownor another interface rather than the requested interface. It can be a valid COM pointer while still exposing the wrong vtable to the native caller.Until CsWin32 can build on a separately extensible COM source-generator package, or custom marshallers can otherwise receive the value identified by
IidParameterIndex, this change projects the implementation-facing parameter asout void*. Implementers can useComOutPtr.FromManagedto performQueryInterfacefor the exact requested IID and transfer the resulting caller-owned interface pointer. This makes the unsafe ABI representation visible, but makes it possible to implement the ABI correctly.Callers are generally unaffected because CsWin32 continues to generate the friendly generic
out Toverload, which supplies the IID forTand converts the returned native interface pointer toT. This is a source change for managed implementations that currently declare the parameter asout object.The prior raw
IID, out objectcalling pattern is no longer available. Callers with only a runtime IID must use the raw output pointer and observe normal COM ownership rules. We are accepting that tradeoff for now and will listen for feedback if the dynamic-IID pattern is important in practice. If the source-generator extensibility described above becomes available, the managedout objectprojection can be reconsidered without sacrificing exact interface identity.Validation
IClassFactoryruntime tests passed on .NET 9 and .NET 10git diff --checkpassed