Open KalleOlaviNiemitalo opened 2 weeks ago
Const
is applied when the underlying definition uses const
, so what you shared looks expected.
Is there a usability issue here? Or are you just pointing out a perceived inconsistency?
I hoped the _In_reads_opt_(nApplications)
could have been treated as implying that the function does not write to the array, and the friendly C# overload would then have used ReadOnlySpan<winmdroot.System.RestartManager.RM_UNIQUE_PROCESS> rgApplications
for this parameter so that my application could have called it without needing writable span.
It's possible the projection could handle this in a different way. @AArnott?
I wouldn't apply Const
here as that represents const
, so either the projection could improve how it handles cases like this based on the existing metadata, or perhaps you're proposing a new attribute.
I kind of expected it might have been a property in NativeArrayInfoAttribute.
Or perhaps the [in]
should be projected to ReadOnlySpan.
The SAL annotation _In_reads_opt_
indicates read-only access, so I think we just need to add [Const]
to rgApplications
.
Here is the metadata in a more human parseable fashion (ILSpy C# decompiled):
[Optional][In][Const][NativeArrayInfo(CountParamIndex = 1)] PWSTR* rgsFileNames
[Optional][In][NativeArrayInfo(CountParamIndex = 3)] RM_UNIQUE_PROCESS* rgApplications,
[Optional][In][Const][NativeArrayInfo(CountParamIndex = 5)] PWSTR* rgsServiceNames
What is the intended difference between [In]
and [Const]
when they appear in the metadata? I believe [In]
by itself is meant to mean the receiver will not change the data pointed to in any way. That would support using ReadOnlySpan
for all three parameters.
PCWSTR
isn't a type in the metadata, so I guess [Const] PWSTR*
is meant to infer PCWSTR*
, which seems to be how CsWin32 is already interpreting it.
If that all seems correct, then I guess CsWin32 just needs to change to infer that [In]
(in the absence of [Out]
also appearing) means a native array will never be changed and thus can be declared as ReadOnlySpan
.
What is the intended difference between
[In]
and[Const]
when they appear in the metadata? I believe[In]
by itself is meant to mean the receiver will not change the data pointed to in any way. That would support usingReadOnlySpan
for all three parameters.PCWSTR
isn't a type in the metadata, so I guess[Const] PWSTR*
is meant to inferPCWSTR*
, which seems to be how CsWin32 is already interpreting it.
Const
just means the keyword const
was used in the original header definition (in this case PCWSTR
uses const
while RM_UNIQUE_PROCESS
does not). It's not applied based on any other semantics. In
, Optional
, and NativeArrayInfo
are based on the SAL annotations.
At least from a metadata perspective, it looks like we're staying true to the headers.
If that all seems correct, then I guess CsWin32 just needs to change to infer that
[In]
(in the absence of[Out]
also appearing) means a native array will never be changed and thus can be declared asReadOnlySpan
.
If you have a reliable way to interpret the existing metadata in the projection, then that seems like the right approach. I wouldn't add Const
here.
I'll move the issue over to CsWin32 then. Thanks.
Microsoft.Windows.CsWin32 0.3.106 (using Microsoft.Windows.SDK.Win32Metadata 60.0.34-preview) generates a C# convenience wrapper for RmRegisterResources, with this signature:
The rgsFileNames and rgsServiceNames parameters are ReadOnlySpan but the rgApplications parameter is Span, even though there is no such difference in the C declaration of RmRegisterResources: https://github.com/microsoft/win32metadata/blob/c2b7ea95b5ae31b76db8f45bbe353b48a58a65f7/generation/WinSDK/RecompiledIdlHeaders/um/RestartManager.h#L206-L214
ildasm
on the metadata shows that the rgsFileNames and rgsServiceNames parameters have a ConstAttribute but the rgApplications parameter doesn't:Is the
const
in thePCWSTR
type leaking to the wrong level of pointer indirection?