Skip to content

Conversation

@manodasanW
Copy link
Member

Various fixes from debugging unit tests

  • Fix vtable ordering
  • Add guid attribute to IDIC types
  • Update AsmResolver version to address try block ordering issues
  • Implement IMarshal interface
  • Fix ICollection clear calls to use CallVirt
  • Implement clear function for ICollection
  • Fix interop assembly names used in unsafe accessors to match what cswinrgen is generating
  • Fix IEnumerator for both scenarios where internal .NET types are used and also to support the generic IEnumerator interface as expected by WinUI

manodasanW and others added 5 commits February 1, 2026 17:36
Correct the IAsyncInfo COM ABI getter implementations to match the Windows docs and expected signatures: rename and reorder get_Id, get_Status and get_ErrorCode methods, fix parameter types and null checks, and marshal ErrorCode via ExceptionMarshaller.ConvertToUnmanaged. Also simplify a MethodSignature.CreateInstance call in InteropTypeDefinitionBuilder by removing an explicit empty parameter list. These changes ensure correct vtable layout, proper pointer validation, and correct marshaling of the error code.
@manodasanW manodasanW requested a review from Sergio0694 February 2, 2026 01:56
Insert blank lines for readability before the `return WellKnownErrorCodes.S_OK;` statements in several try blocks of src/WinRT.Runtime2/InteropServices/ProjectionImpls/IMarshalImpl.cs. No behavioral changes — purely formatting to improve visual separation between the marshaler calls and their success returns.
Add null checks for out pointer parameters in IMarshalImpl to avoid dereferencing null and to return WellKnownErrorCodes.E_POINTER early. Updated methods: GetUnmarshalClass (pCid), GetMarshalSizeMax (pSize), and UnmarshalInterface (ppv). Each check returns E_POINTER if the caller passed a null out pointer, and existing default/initialization of out values is preserved before the try block.
Removed unnecessary inline comments that prefaced .Methods.Add calls to reduce noise and improve code readability. Changes affect InteropTypeDefinitionBuilder.SzArray.cs, InteropTypeDefinitionBuilder.UserDefinedType.cs, InteropTypeDefinitionBuilder.cs, and InteropTypeDefinitionFactory.IReadOnlyCollectionKeyValuePair2.cs.
Rename IBindableIteratorAdapter to BindableIEnumeratorAdapter and update usages. The file was renamed, the constructor and GetInstance factory were updated, the ConditionalWeakTable now maps to BindableIEnumeratorAdapter, and IEnumeratorImpl calls were changed to use the new adapter (Current, HasCurrent, MoveNext). This clarifies naming to match IEnumerator semantics.
Add bindable adapters and helper methods for marshaling System.Collections.IEnumerable/IEnumerator to IBindableIterable/IBindableIterator. New files BindableIEnumerableAdapter.cs and BindableIEnumerableMethods.cs provide the unmanaged marshaling/First/GetEnumerator logic. Refactor IEnumerable plumbing to call BindableIEnumerableMethods and remove older private adapter code from ABI/System/Collections/IEnumerable.cs. Update WindowsRuntimeEnumerable and WindowsRuntimeList to use the new methods. Enhance BindableIEnumeratorAdapter: implement IEnumerator<object> and IEnumeratorAdapter, expose Enumerator, adjust construction/unwrapping logic and introduce a ConditionalWeakTable and factory helper. Also update IEnumerableMethods (Collections) to properly unwrap nested IEnumeratorAdapter<object> and related cases. Minor using/pragma cleanups in IDictionaryMethods and IEnumerable ABI file.
Simplify marshaller method registration by using Methods.Add instead of AddMethodImplementation and remove redundant inline comments. Updated InteropTypeDefinitionBuilder.Delegate.cs and InteropTypeDefinitionBuilder.KeyValuePair.cs to add ComputeVtables, GetOrCreateComInterfaceForObject, and CreateObject via Methods.Add and clean up duplicate explanatory comments. This makes method wiring more consistent and reduces noisy comment clutter.
Sergio0694 and others added 11 commits February 2, 2026 11:51
Introduce ABI.System.Collections.IEnumerableMethods as an interop shim for System.Collections.IEnumerable.GetEnumerator (marked Obsolete and EditorBrowsable(Never)) to centralize the ABI-facing entry point. Update WindowsRuntimeEnumerable, WindowsRuntimeList and the internal interface implementation to call the new IEnumerableMethods.GetEnumerator instead of BindableIEnumerableMethods.GetEnumerator.
Expand comment explaining fallback when GetRuntimeClassName fails: treat the object as an opaque IInspectable and note scenarios where this occurs (e.g. MemoryBuffer.CreateReference). Clarifies caller expectations (consuming projected interfaces via dynamic interface casts) and adds a small formatting tweak before the return.
Correct a spelling mistake in BindableIEnumerableAdapter.cs comment: 'tirmming' was changed to 'trimming'. The comment explains that trimming will automatically keep code for the constructed IEnumerator<object> if the code path is reachable.
Replace direct calls to TIIterableMethods.First(...) with IEnumerableMethods<T>.GetEnumerator<TIIterableMethods>(...) across WindowsRuntime collection types for consistent enumerator retrieval. Affected classes: WindowsRuntimeDictionary, WindowsRuntimeEnumerable, WindowsRuntimeList, WindowsRuntimeObservableMap, WindowsRuntimeObservableVector, WindowsRuntimeReadOnlyDictionary, and WindowsRuntimeReadOnlyList. This centralizes enumerator creation and improves consistency for different iterable method implementations.
Add support for nested Enumerator generic types used by dictionary collections. InteropTypeDiscovery now calls TryTrackGenericTypeInstance for DictionaryKeyCollection/ValueCollection and ReadOnlyDictionaryKey/ValueCollection .Enumerator generic instances so the generator can discover those types. InteropReferences exposes TypeReference properties for each nested Enumerator (DictionaryKeyCollection2Enumerator, DictionaryValueCollection2Enumerator, ReadOnlyDictionaryKeyCollection2Enumerator, ReadOnlyDictionaryValueCollection2Enumerator).

To enable resolution of those nested types at runtime, the nested Enumerator classes in DictionaryKeyCollection, DictionaryValueCollection, ReadOnlyDictionaryKeyCollection and ReadOnlyDictionaryValueCollection were changed from private to public and annotated with Obsolete (using WindowsRuntimeConstants private-implementation diagnostic values) and EditorBrowsableState.Never to indicate they are private implementation details.
Rename WindowsRuntimeIterator to WindowsRuntimeEnumerator (class and file) to better reflect its role as an IEnumerator wrapper. Update references in src/WinRT.Runtime2/ABI/System/Collections/IEnumerator.cs to construct WindowsRuntimeEnumerator and adjust the class declaration, constructor, and XML docs accordingly.
Handle a rare null-interfacePointer case (e.g. WeakReference<T> rehydration) by disallowing static callbacks, QueryInterface-ing for IInspectable, and releasing the acquired pointer on exit. Reorganize CreateObject logic: move runtime class name retrieval and HSTRING lifetime into a try/finally, attempt object creation via ObjectComWrappersCallback/UnsealedObjectComWrappersCallback, walk most-derived marshalling info, and fall back to an opaque WindowsRuntimeInspectable. Add WindowsRuntimeComWrappersExceptions.ThrowInvalidOperationException helper (with DoesNotReturn/StackTraceHidden) and add Diagnostics usings.
…#2221)

* Add CreateObject API for unsealed RCW

Introduce a CreateObject method for unsealed Windows Runtime object callbacks. Added a static abstract CreateObject(void* value, out CreatedWrapperFlags) to IWindowsRuntimeUnsealedObjectComWrappersCallback with XML docs explaining it's used when TryCreateObject fails and mirrors IWindowsRuntimeObjectComWrappersCallback.CreateObject. Updated WindowsRuntimeUnsealedObjectComWrappersCallback to declare the abstract CreateObject and implemented the host to forward calls to the generic TCallback.CreateObject. This enables creating managed RCWs for unsealed/native objects when no more specific wrapper is resolved.

* Add CreateObject methods for WinRT ABIs

Implement static CreateObject factory methods in IEnumerable, IEnumerator, IList and IAsyncAction ABI callback classes. Each method uses WindowsRuntimeComWrappersMarshal.CreateObjectReferenceUnsafe with the appropriate IID (IBindableIterable, IBindableIterator, IBindableVector, IAsyncAction), returns the corresponding managed wrapper (WindowsRuntimeEnumerable, WindowsRuntimeEnumerator, WindowsRuntimeList, WindowsRuntimeAsyncAction) and outputs CreatedWrapperFlags. This allows ComWrappers to create proper managed wrappers for external WinRT COM objects.

* Make InspectableObjectReference init-only

Replace the property setter that used Interlocked.CompareExchange with an init accessor for _inspectableObjectReference. This simplifies initialization by making the reference assignable only during object initialization (via init), removing the previous CAS-based setter. The change assumes initialization-time assignment semantics and removes the runtime interlocked operation.

* Improve GetRuntimeClassName handling in ComWrappers

Refactor WindowsRuntimeComWrappers to handle runtime class name retrieval and unsealed type callbacks more robustly. The code now checks for GetRuntimeClassName success and, when available, converts the HSTRING, invokes UnsealedObjectComWrappersCallback.TryCreateObject, and then walks most-derived marshalling info via WindowsRuntimeMarshallingInfo to create the appropriate managed wrapper. HSTRING is freed in a finally block. If no derived/recognized type is found, the code falls back to calling the unsealed-type callback (if present) and only returns an opaque IInspectable wrapper as the last resort. Added explanatory comments and streamlined return paths.

* Add CreateObject callback and reference

Define and implement the CreateObject callback used by IWindowsRuntimeUnsealedObjectComWrappersCallback. Adds a static CreateObject method on the generated callback type (signature: object CreateObject(void* value, out CreatedWrapperFlags wrapperFlags)) that invokes WindowsRuntimeComWrappersMarshal.CreateObjectReferenceUnsafe and constructs a NativeObject, and registers it as the method implementation. Also adds a MemberReference for the CreateObject method in InteropReferences so the signature can be referenced during generation. This enables unsealed object creation support for the COM wrappers pipeline.

* Correct comment to match CreateObject method

Update the method summary comment to reference 'CreateObject' instead of 'TryCreateObject', aligning the comment with the MethodDefinition in InteropTypeDefinitionBuilder. This is a documentation-only change with no behavioral impact.

* Document fallback when GetRuntimeClassNameUnsafe fails

Update XML remarks for IWindowsRuntimeUnsealedObjectComWrappersCallback.CreateObject to note the method can also be called if IInspectableVftbl.GetRuntimeClassNameUnsafe fails. This is a documentation-only clarification in src/WinRT.Runtime2/InteropServices/Callbacks/IWindowsRuntimeUnsealedObjectComWrappersCallback.cs and does not change runtime behavior.

* Reflow comments and fix typo in ComWrappers

Reformatted a long explanatory comment in src/WinRT.Runtime2/InteropServices/WindowsRuntimeComWrappers.cs for improved readability and fixed a typo (removed duplicated "with" -> "without"). No functional code changes; comment clarifies the fallback unsealed-type callback behavior used to produce specialized RCWs and avoid extra dynamic interface casts.

* Fix unsealed callback in codewriters

* Add test for non projected class

* Fix default value

---------

Co-authored-by: Manodasan Wignarajah <mawign@microsoft.com>
@manodasanW manodasanW enabled auto-merge (squash) February 4, 2026 07:10
@manodasanW manodasanW merged commit 9421351 into staging/3.0 Feb 4, 2026
11 checks passed
@Sergio0694 Sergio0694 deleted the manodasanw/InteropFixes4-1 branch February 4, 2026 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants