Skip to content

Qualify special string typedefs (PCWSTR) to Windows.Win32.Foundation for non-Win32 metadata - #1786

Merged
Jevan Saks (jevansaks) merged 1 commit into
mainfrom
user/jevansa/pcwstr-array-friendly-overload
Aug 14, 2026
Merged

Qualify special string typedefs (PCWSTR) to Windows.Win32.Foundation for non-Win32 metadata#1786
Jevan Saks (jevansaks) merged 1 commit into
mainfrom
user/jevansa/pcwstr-array-friendly-overload

Conversation

@jevansaks

@jevansaks Jevan Saks (jevansaks) commented Aug 13, 2026

Copy link
Copy Markdown
Member

Problem

When generating C# from a non-Windows.Win32 metadata assembly (e.g. a winmd built from a UDK header, common namespace OSClient), a parameter typed _In_reads_opt_(count) LPCWSTR* / [Const] PWSTR* (projected as PCWSTR*) fails to compile:

error CS0234: The type or namespace name 'Foundation' does not exist in the namespace 'OSClient'
error CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type

CsWin32 qualified the special string typedef PCWSTR under the consuming assembly's own root namespace — OSClient.Foundation.PCWSTR — which does not exist. It should reference global::Windows.Win32.Foundation.PCWSTR, where the type actually lives.

Root cause

This reproduces only in the configuration OSClient uses: a single Generator (no SuperGenerator), with the Windows.Win32 projection supplied as a referenced assembly rather than a sibling generator. In that setup there is no Windows.Win32 generator to delegate special-typedef emission to, so the special typedefs must be referenced under Windows.Win32.Foundation.

Two places built the wrong qualification for the projected PCWSTR*:

  1. Generator.RequestSpecialTypeDefStruct computed the fully-qualified name from this.Namespace (the consuming assembly's common namespace → OSClient). The delegation that fixes this up only runs when a SuperGenerator is present, so in the single-generator case the name stayed OSClient.Foundation.PCWSTR. This is the element type used by the extern/interface signature, the in PCWSTR friendly overload, and the fixed block. This is the primary CS0234.

  2. Generator.FriendlyOverloads.PCWSTRTypeSyntax (used only by the ReadOnlySpan<string> friendly overload generated for a counted array, [Const, NativeArrayInfo] PWSTR*) hard-coded the ArrayPool<PCWSTR> element type to the winmdroot alias, which for non-Win32 metadata points at the wrong assembly.

Fix

  1. RequestSpecialTypeDefStruct now qualifies special typedefs under Windows.Win32.Foundation for non-Win32 metadata (rootNamespace = IsWin32Sdk ? this.Namespace : "Windows.Win32").
  2. PCWSTRTypeSyntax is now an instance member using Win32NamespacePrefix, matching how the parameter type itself is qualified.

Both changes are no-ops for the Windows.Win32 SDK itself (byte-identical output — verified by Everything_NoFriendlyOverloads).

Tests

Adds SelfContained.winmd, a single-generator P/Invoke fixture that faithfully reproduces the OSClient configuration, and a theory SingleGeneratorQualifiesSpecialTypeDefToWin32Namespace covering both projections:

Both fail with CS0234 on the pre-fix generator and compile cleanly with the fix.

Fixes the CsWin32 sanity-check failure in OSClient PR 16236433.

@jevansaks Jevan Saks (jevansaks) changed the title Don't project a pointer to a string-pointer typedef (PCWSTR*) as in Fix PCWSTR* (string-pointer array) friendly-overload projection for non-Win32 metadata Aug 13, 2026
@jevansaks
Jevan Saks (jevansaks) force-pushed the user/jevansa/pcwstr-array-friendly-overload branch from 8b2cbfd to 1276962 Compare August 13, 2026 21:53
@jevansaks Jevan Saks (jevansaks) changed the title Fix PCWSTR* (string-pointer array) friendly-overload projection for non-Win32 metadata Qualify PCWSTR correctly in ReadOnlySpan<string> array marshaling for non-Win32 metadata Aug 13, 2026
@jevansaks
Jevan Saks (jevansaks) marked this pull request as ready for review August 13, 2026 22:46
@jevansaks
Jevan Saks (jevansaks) force-pushed the user/jevansa/pcwstr-array-friendly-overload branch from 1276962 to 1df91d2 Compare August 13, 2026 23:07
…for non-Win32 metadata

When CsWin32 projects a non-Windows.Win32 metadata assembly with a single
Generator (no SuperGenerator, with the Windows.Win32 projection provided as a
referenced assembly -- the OSClient build configuration), references to the
special string typedefs (PCWSTR, PCSTR, ...) were qualified under the consuming
assembly's own root namespace (e.g. OSClient.Foundation.PCWSTR), which does not
exist and fails to compile with CS0234.

Two places produced the mis-qualification for a `[Const] PWSTR*` parameter
(projected as PCWSTR*):

1. RequestSpecialTypeDefStruct built the fully-qualified name from this.Namespace
   (the consuming assembly's common namespace). For non-Win32 metadata the type
   lives in Windows.Win32.Foundation (provided by a delegated generator or a
   referenced assembly), so qualify it there. This covers the no-count case
   (in PCWSTR), the fixed block, and the extern/interface method signature.

2. The ReadOnlySpan<string> friendly overload generated for a counted array
   ([Const, NativeArrayInfo] PWSTR*) hard-coded the ArrayPool<PCWSTR> element type
   to the winmdroot alias. Qualify it with Win32NamespacePrefix to match how the
   parameter type is qualified.

Both changes are no-ops for the Windows.Win32 SDK itself (byte-identical output).

Adds SelfContained.winmd, a single-generator P/Invoke fixture reproducing the
OSClient configuration, with a theory covering both the no-count (Foo) and
counted (Bar) projections.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jevansaks
Jevan Saks (jevansaks) force-pushed the user/jevansa/pcwstr-array-friendly-overload branch from 1df91d2 to b68f2df Compare August 14, 2026 00:25
@jevansaks Jevan Saks (jevansaks) changed the title Qualify PCWSTR correctly in ReadOnlySpan<string> array marshaling for non-Win32 metadata Qualify special string typedefs (PCWSTR) to Windows.Win32.Foundation for non-Win32 metadata Aug 14, 2026
@jevansaks
Jevan Saks (jevansaks) marked this pull request as draft August 14, 2026 00:26
@jevansaks
Jevan Saks (jevansaks) marked this pull request as ready for review August 14, 2026 17:41
@jevansaks
Jevan Saks (jevansaks) enabled auto-merge (squash) August 14, 2026 17:41
@jevansaks
Jevan Saks (jevansaks) merged commit b0f1e79 into main Aug 14, 2026
20 checks passed
@jevansaks
Jevan Saks (jevansaks) deleted the user/jevansa/pcwstr-array-friendly-overload branch August 14, 2026 17:58
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.

Add unit tests for code generation

2 participants