Skip to content

Commit c6fb8ce

Browse files
jtschustermatouskozak
authored andcommitted
Set out parameters to default instead of using SkipInit in Interop generators (dotnet#101076)
* Set `out` parameters to default instead of using SkipInit * Assert value after P/Invoke
1 parent f5cd644 commit c6fb8ce

File tree

6 files changed

+76
-9
lines changed

6 files changed

+76
-9
lines changed

src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/MarshallerHelpers.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,14 @@ public static StatementSyntax SkipInitOrDefaultInit(TypePositionInfo info, StubC
263263
}
264264
}
265265

266+
public static StatementSyntax DefaultInit(TypePositionInfo info, StubCodeContext context)
267+
{
268+
// Assign out params to default
269+
return AssignmentStatement(
270+
IdentifierName(info.InstanceIdentifier),
271+
LiteralExpression(SyntaxKind.DefaultLiteralExpression, Token(SyntaxKind.DefaultKeyword)));
272+
}
273+
266274
/// <summary>
267275
/// Get the marshalling direction for a given <see cref="TypePositionInfo"/> in a given <see cref="StubCodeContext"/>.
268276
/// For example, an out parameter is marshalled in the <see cref="MarshalDirection.UnmanagedToManaged"/> direction in a <see cref="MarshalDirection.ManagedToUnmanaged"/> stub,

src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/VariableDeclarations.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public static VariableDeclarations GenerateDeclarationsForManagedToUnmanaged(Bou
2626

2727
if (info.RefKind == RefKind.Out)
2828
{
29-
initializations.Add(MarshallerHelpers.SkipInitOrDefaultInit(info, context));
29+
initializations.Add(MarshallerHelpers.DefaultInit(info, context));
3030
}
3131

3232
// Declare variables for parameters

src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/UnmanagedToManagedCustomMarshallingTests.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Runtime.InteropServices;
88
using System.Runtime.InteropServices.Marshalling;
99
using System.Threading;
10+
using Microsoft.Diagnostics.Runtime;
1011
using SharedTypes;
1112
using Xunit;
1213
using static ComInterfaceGenerator.Tests.UnmanagedToManagedCustomMarshallingTests;
@@ -156,11 +157,11 @@ public unsafe void ValidateArrayElementsAndOutParameterNotFreed_Stateless()
156157
try
157158
{
158159
var values = new int[] { 1, 32, 63, 124, 255 };
159-
160160
int freeCalls = IntWrapperMarshallerToIntWithFreeCounts.NumCallsToFree;
161-
162-
NativeExportsNE.UnmanagedToManagedCustomMarshalling.SumAndSetNativeObjectData(wrapper, values, values.Length, out int _);
163-
161+
int oldValue = startingValue + 100;
162+
NativeExportsNE.UnmanagedToManagedCustomMarshalling.SumAndSetNativeObjectData(wrapper, values, values.Length, out oldValue);
163+
Assert.Equal(values.Sum(), impl.GetData().i);
164+
Assert.Equal(startingValue, oldValue);
164165
Assert.Equal(freeCalls, IntWrapperMarshallerToIntWithFreeCounts.NumCallsToFree);
165166
}
166167
finally
@@ -181,11 +182,11 @@ public unsafe void ValidateArrayElementsByRefFreed_Stateless()
181182
try
182183
{
183184
var values = new int[] { 1, 32, 63, 124, 255 };
184-
185185
int freeCalls = IntWrapperMarshallerToIntWithFreeCounts.NumCallsToFree;
186-
187-
NativeExportsNE.UnmanagedToManagedCustomMarshalling.SumAndSetNativeObjectData(wrapper, ref values, values.Length, out int _);
188-
186+
int oldValue = startingValue + 100;
187+
NativeExportsNE.UnmanagedToManagedCustomMarshalling.SumAndSetNativeObjectData(wrapper, ref values, values.Length, out oldValue);
188+
Assert.Equal(values.Sum(), impl.GetData().i);
189+
Assert.Equal(startingValue, oldValue);
189190
Assert.Equal(freeCalls + values.Length, IntWrapperMarshallerToIntWithFreeCounts.NumCallsToFree);
190191
}
191192
finally
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Diagnostics;
5+
using System.Runtime.InteropServices;
6+
using SharedTypes;
7+
using Xunit;
8+
9+
namespace LibraryImportGenerator.IntegrationTests
10+
{
11+
partial class NativeExportsNE
12+
{
13+
public partial class RefParameters
14+
{
15+
[LibraryImport(NativeExportsNE_Binary, EntryPoint = "out_params")]
16+
public static partial int OutParameters(out int values, out IntFields numValues);
17+
}
18+
}
19+
public class RefParameters
20+
{
21+
[Fact]
22+
public void OutParametersAreDefaultInitialized()
23+
{
24+
int myInt = 12;
25+
IntFields myIntFields = new IntFields() { a = 12, b = 12, c = 12 };
26+
NativeExportsNE.RefParameters.OutParameters(out myInt, out myIntFields);
27+
Debug.Assert(myInt == default);
28+
Debug.Assert(myIntFields.a == default && myIntFields.b == default && myIntFields.c == default);
29+
}
30+
}
31+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Diagnostics;
6+
using System.Linq;
7+
using System.Runtime.InteropServices;
8+
using System.Text;
9+
using System.Threading.Tasks;
10+
using SharedTypes;
11+
12+
namespace NativeExports
13+
{
14+
public static unsafe class RefParameters
15+
{
16+
[UnmanagedCallersOnly(EntryPoint = "out_params")]
17+
public static void EnsureOutParamIsDefault(int* ri, [DNNE.C99Type("struct int_fields*")]IntFields* rif)
18+
{
19+
int i = *ri;
20+
Debug.Assert(i == default);
21+
IntFields _if = *rif;
22+
Debug.Assert(_if.a == default && _if.b == default && _if.c == default);
23+
}
24+
}
25+
}

src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/VirtualMethodTables.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,15 @@ public static void ExchangeNativeObjectData([DNNE.C99Type("struct INativeObject*
198198
[DNNE.C99DeclCode("struct INativeObject;")]
199199
public static void SumAndSetData([DNNE.C99Type("struct INativeObject*")] NativeObjectInterface* obj, int* values, int numValues, int* oldValue)
200200
{
201+
Debug.Assert(*oldValue == default);
201202
obj->VTable->sumAndSetData(obj, values, numValues, oldValue);
202203
}
203204

204205
[UnmanagedCallersOnly(EntryPoint = "sum_and_set_native_object_data_with_ref")]
205206
[DNNE.C99DeclCode("struct INativeObject;")]
206207
public static void SumAndSetDataWithRef([DNNE.C99Type("struct INativeObject*")] NativeObjectInterface* obj, int** values, int numValues, int* oldValue)
207208
{
209+
Debug.Assert(*oldValue == default);
208210
obj->VTable->sumAndSetDataWithRef(obj, values, numValues, oldValue);
209211
}
210212

0 commit comments

Comments
 (0)