Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/design/libraries/DllImportGenerator/StructMarshalling.md16
-rw-r--r--src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs44
-rw-r--r--src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln219
-rw-r--r--src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/AnalyzerReleases.Unshipped.md1
-rw-r--r--src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/AnalyzerDiagnostics.cs1
-rw-r--r--src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/ManualTypeMarshallingAnalyzer.cs63
-rw-r--r--src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/PInvokeStubCodeGenerator.cs4
-rw-r--r--src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.Designer.cs18
-rw-r--r--src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.resx6
-rw-r--r--src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs52
-rw-r--r--src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SyntaxExtensions.cs33
-rw-r--r--src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/SpanMarshallers.cs28
-rw-r--r--src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/ManualTypeMarshallingAnalyzerTests.cs129
-rw-r--r--src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs85
14 files changed, 418 insertions, 281 deletions
diff --git a/docs/design/libraries/DllImportGenerator/StructMarshalling.md b/docs/design/libraries/DllImportGenerator/StructMarshalling.md
index 2852880103c..2b4f33f8233 100644
--- a/docs/design/libraries/DllImportGenerator/StructMarshalling.md
+++ b/docs/design/libraries/DllImportGenerator/StructMarshalling.md
@@ -54,14 +54,16 @@ partial struct TNative
}
```
-The analyzer will report an error if neither the construtor nor the ToManaged method is defined. When one of those two methods is missing, the direction of marshalling (managed to native/native to managed) that relies on the missing method is considered unsupported for the corresponding managed type. The FreeNative method is only required when there are resources that need to be released.
+The analyzer will report an error if neither the constructor nor the `ToManaged` method is defined. When one of those two methods is missing, the direction of marshalling (managed to native/native to managed) that relies on the missing method is considered unsupported for the corresponding managed type. The `FreeNative` method is only required when there are resources that need to be released.
> :question: Does this API surface and shape work for all marshalling scenarios we plan on supporting? It may have issues with the current "layout class" by-value `[Out]` parameter marshalling where the runtime updates a `class` typed object in place. We already recommend against using classes for interop for performance reasons and a struct value passed via `ref` or `out` with the same members would cover this scenario.
If the native type `TNative` also has a public `Value` property, then the value of the `Value` property will be passed to native code instead of the `TNative` value itself. As a result, the type `TNative` will be allowed to be non-blittable and the type of the `Value` property will be required to be blittable. If the `Value` property is settable, then when marshalling in the native-to-managed direction, a default value of `TNative` will have its `Value` property set to the native value. If `Value` does not have a setter, then marshalling from native to managed is not supported.
-A `ref` or `ref readonly` typed `Value` property is unsupported. If a ref-return is required, the type author can supply a `GetPinnableReference` method on the native type. If a `GetPinnableReference` method is supplied, then the `Value` property must have a pointer-sized primitive type.
+If a `Value` property is provided, the developer may also provide a ref-returning or readonly-ref-returning `GetPinnableReference` method. The `GetPinnableReference` method will be called before the `Value` property getter is called. The ref returned by `GetPinnableReference` will be pinned with a `fixed` statement, but the pinned value will not be used (it acts exclusively as a side-effect).
+
+A `ref` or `ref readonly` typed `Value` property is unsupported. If a ref-return is required, the type author can supply a `GetPinnableReference` method on the native type to pin the desired `ref` to return and then use `System.Runtime.CompilerServices.Unsafe.AsPointer` to get a pointer from the `ref` that will have already been pinned by the time the `Value` getter is called.
```csharp
[NativeMarshalling(typeof(TMarshaler))]
@@ -72,14 +74,14 @@ public struct TManaged
public struct TMarshaler
{
- public TNative(TManaged managed) {}
+ public TMarshaler(TManaged managed) {}
public TManaged ToManaged() {}
public void FreeNative() {}
public ref TNative GetPinnableReference() {}
- public TNative Value { get; set; }
+ public TNative* Value { get; set; }
}
```
@@ -88,7 +90,7 @@ public struct TMarshaler
#### Pinning
-Since C# 7.3 added a feature to enable custom pinning logic for user types, we should also add support for custom pinning logic. If the user provides a `GetPinnableReference` method that matches the requirements to be used in a `fixed` statement and the pointed-to type is blittable, then we will support using pinning to marshal the managed value when possible. The analyzer should issue a warning when the pointed-to type would not match the final native type, accounting for the `Value` property on the native type. Since `MarshalUsingAttribute` is applied at usage time instead of at type authoring time, we will not enable the pinning feature since the implementation of `GetPinnableReference` unless the pointed-to return type matches the native type.
+Since C# 7.3 added a feature to enable custom pinning logic for user types, we should also add support for custom pinning logic. If the user provides a `GetPinnableReference` method on the managed type that matches the requirements to be used in a `fixed` statement and the pointed-to type is blittable, then we will support using pinning to marshal the managed value when possible. The analyzer should issue a warning when the pointed-to type would not match the final native type, accounting for the `Value` property on the native type. Since `MarshalUsingAttribute` is applied at usage time instead of at type authoring time, we will not enable the pinning feature since the implementation of `GetPinnableReference` is likely designed to match the default marshalling rules provided by the type author, not the rules provided by the marshaller provided by the `MarshalUsingAttribute`.
#### Caller-allocated memory
@@ -100,14 +102,14 @@ partial struct TNative
public TNative(TManaged managed, Span<byte> buffer) {}
public const int BufferSize = /* */;
-
+
public const bool RequiresStackBuffer = /* */;
}
```
When these members are present, the source generator will call the two-parameter constructor with a possibly stack-allocated buffer of `BufferSize` bytes when a stack-allocated buffer is usable. If a stack-allocated buffer is a requirement, the `RequiresStackBuffer` field should be set to `true` and the `buffer` will be guaranteed to be allocated on the stack. Setting the `RequiresStackBuffer` field to `false` is the same as omitting the field definition. Since a dynamically allocated buffer is not usable in all scenarios, for example Reverse P/Invoke and struct marshalling, a one-parameter constructor must also be provided for usage in those scenarios. This may also be provided by providing a two-parameter constructor with a default value for the second parameter.
-Type authors can pass down the `buffer` pointer to native code by defining a `GetPinnableReference()` method on the native type that returns a reference to the first element of the span. When the `RequiresStackBuffer` field is set to `true`, the type author is free to use APIs that would be dangerous in non-stack-allocated scenarios such as `MemoryMarshal.GetReference()` and `Unsafe.AsPointer()`.
+Type authors can pass down the `buffer` pointer to native code by defining a `Value` property that returns a pointer to the first element, generally through code using `MemoryMarshal.GetReference()` and `Unsafe.AsPointer`. If `RequiresStackBuffer` is not provided or set to `false`, the `buffer` span must be pinned to be used safely. The `buffer` span can be pinned by defining a `GetPinnableReference()` method on the native type that returns a reference to the first element of the span.
### Usage
diff --git a/src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs b/src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs
index 2293743aa87..91e350038b8 100644
--- a/src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs
+++ b/src/libraries/Common/src/System/Runtime/InteropServices/ArrayMarshaller.cs
@@ -32,20 +32,8 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling
}
public ArrayMarshaller(T[]? managed, int sizeOfNativeElement)
+ :this(managed, Span<byte>.Empty, sizeOfNativeElement)
{
- _allocatedMemory = default;
- _sizeOfNativeElement = sizeOfNativeElement;
- if (managed is null)
- {
- _managedArray = null;
- NativeValueStorage = default;
- return;
- }
- _managedArray = managed;
- // Always allocate at least one byte when the array is zero-length.
- int spaceToAllocate = Math.Max(managed.Length * _sizeOfNativeElement, 1);
- _allocatedMemory = Marshal.AllocCoTaskMem(spaceToAllocate);
- NativeValueStorage = new Span<byte>((void*)_allocatedMemory, spaceToAllocate);
}
public ArrayMarshaller(T[]? managed, Span<byte> stackSpace, int sizeOfNativeElement)
@@ -94,8 +82,7 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling
{
get
{
- Debug.Assert(_managedArray is null || _allocatedMemory != IntPtr.Zero);
- return (byte*)_allocatedMemory;
+ return (byte*)Unsafe.AsPointer(ref GetPinnableReference());
}
set
{
@@ -116,10 +103,7 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling
public void FreeNative()
{
- if (_allocatedMemory != IntPtr.Zero)
- {
- Marshal.FreeCoTaskMem(_allocatedMemory);
- }
+ Marshal.FreeCoTaskMem(_allocatedMemory);
}
}
@@ -141,20 +125,8 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling
}
public PtrArrayMarshaller(T*[]? managed, int sizeOfNativeElement)
+ :this(managed, Span<byte>.Empty, sizeOfNativeElement)
{
- _allocatedMemory = default;
- _sizeOfNativeElement = sizeOfNativeElement;
- if (managed is null)
- {
- _managedArray = null;
- NativeValueStorage = default;
- return;
- }
- _managedArray = managed;
- // Always allocate at least one byte when the array is zero-length.
- int spaceToAllocate = Math.Max(managed.Length * _sizeOfNativeElement, 1);
- _allocatedMemory = Marshal.AllocCoTaskMem(spaceToAllocate);
- NativeValueStorage = new Span<byte>((void*)_allocatedMemory, spaceToAllocate);
}
public PtrArrayMarshaller(T*[]? managed, Span<byte> stackSpace, int sizeOfNativeElement)
@@ -203,8 +175,7 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling
{
get
{
- Debug.Assert(_managedArray is null || _allocatedMemory != IntPtr.Zero);
- return (byte*)_allocatedMemory;
+ return (byte*)Unsafe.AsPointer(ref GetPinnableReference());
}
set
{
@@ -226,10 +197,7 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling
public void FreeNative()
{
- if (_allocatedMemory != IntPtr.Zero)
- {
- Marshal.FreeCoTaskMem(_allocatedMemory);
- }
+ Marshal.FreeCoTaskMem(_allocatedMemory);
}
}
}
diff --git a/src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln b/src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln
index ae6e8fc0cc7..54f3e3fb53c 100644
--- a/src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln
+++ b/src/libraries/System.Runtime.InteropServices/System.Runtime.InteropServices.sln
@@ -1,4 +1,8 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31808.319
+MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", "..\..\coreclr\System.Private.CoreLib\System.Private.CoreLib.csproj", "{94B59BA0-491F-4B59-ADFF-A057EC3EC835}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}"
@@ -9,7 +13,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServ
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.CompilerServices.Unsafe", "..\System.Runtime.CompilerServices.Unsafe\src\System.Runtime.CompilerServices.Unsafe.ilproj", "{04BA3E3C-6979-4792-B19E-C797AD607F42}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Interop.DllImportGenerator", "gen\DllImportGenerator\DllImportGenerator.csproj", "{07F19F91-D438-428D-99F0-61DAD87E78BA}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DllImportGenerator", "gen\DllImportGenerator\DllImportGenerator.csproj", "{07F19F91-D438-428D-99F0-61DAD87E78BA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Interop.SourceGeneration", "gen\Microsoft.Interop.SourceGeneration\Microsoft.Interop.SourceGeneration.csproj", "{768B77B0-EA45-469D-B39E-545EB72F5A43}"
EndProject
@@ -17,7 +21,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.InteropServi
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.InteropServices", "src\System.Runtime.InteropServices.csproj", "{4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Interop.Ancillary", "tests\Ancillary.Interop\Ancillary.Interop.csproj", "{79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ancillary.Interop", "tests\Ancillary.Interop\Ancillary.Interop.csproj", "{79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DllImportGenerator.Tests", "tests\DllImportGenerator.Tests\DllImportGenerator.Tests.csproj", "{57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}"
EndProject
@@ -27,7 +31,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.InteropServi
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.InteropServices.Tests", "tests\System.Runtime.InteropServices.UnitTests\System.Runtime.InteropServices.Tests.csproj", "{049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Interop.Tests.NativeExports", "tests\TestAssets\NativeExports\NativeExports.csproj", "{866D295E-424A-4747-9417-CD7746936138}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeExports", "tests\TestAssets\NativeExports\NativeExports.csproj", "{866D295E-424A-4747-9417-CD7746936138}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedTypes", "tests\TestAssets\SharedTypes\SharedTypes.csproj", "{D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}"
EndProject
@@ -38,18 +42,27 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{D893B9AA-57C5-49E3-97B1-12CC62D84307}"
EndProject
Global
+ GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ ..\System.Private.CoreLib\src\System.Private.CoreLib.Shared.projitems*{94b59ba0-491f-4b59-adff-a057ec3ec835}*SharedItemsImports = 5
+ EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Checked|Any CPU = Checked|Any CPU
+ Checked|x64 = Checked|x64
+ Checked|x86 = Checked|x86
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
- Checked|Any CPU = Checked|Any CPU
- Checked|x64 = Checked|x64
- Checked|x86 = Checked|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|Any CPU.ActiveCfg = Checked|x64
+ {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|Any CPU.Build.0 = Checked|x64
+ {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x64.ActiveCfg = Checked|x64
+ {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x64.Build.0 = Checked|x64
+ {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x86.ActiveCfg = Checked|x86
+ {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x86.Build.0 = Checked|x86
{94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Debug|Any CPU.ActiveCfg = Debug|x64
{94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Debug|Any CPU.Build.0 = Debug|x64
{94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Debug|x64.ActiveCfg = Debug|x64
@@ -62,12 +75,12 @@ Global
{94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Release|x64.Build.0 = Release|x64
{94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Release|x86.ActiveCfg = Release|x86
{94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Release|x86.Build.0 = Release|x86
- {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|Any CPU.ActiveCfg = Checked|x64
- {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|Any CPU.Build.0 = Checked|x64
- {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x64.ActiveCfg = Checked|x64
- {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x64.Build.0 = Checked|x64
- {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x86.ActiveCfg = Checked|x86
- {94B59BA0-491F-4B59-ADFF-A057EC3EC835}.Checked|x86.Build.0 = Checked|x86
+ {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|x64.Build.0 = Debug|Any CPU
+ {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|x86.Build.0 = Debug|Any CPU
{1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -80,12 +93,12 @@ Global
{1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Release|x64.Build.0 = Release|Any CPU
{1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Release|x86.ActiveCfg = Release|Any CPU
{1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Release|x86.Build.0 = Release|Any CPU
- {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|x64.ActiveCfg = Debug|Any CPU
- {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|x64.Build.0 = Debug|Any CPU
- {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|x86.ActiveCfg = Debug|Any CPU
- {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA}.Checked|x86.Build.0 = Debug|Any CPU
+ {1B248B4C-7584-4C04-850A-A50EB592052C}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {1B248B4C-7584-4C04-850A-A50EB592052C}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {1B248B4C-7584-4C04-850A-A50EB592052C}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {1B248B4C-7584-4C04-850A-A50EB592052C}.Checked|x64.Build.0 = Debug|Any CPU
+ {1B248B4C-7584-4C04-850A-A50EB592052C}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {1B248B4C-7584-4C04-850A-A50EB592052C}.Checked|x86.Build.0 = Debug|Any CPU
{1B248B4C-7584-4C04-850A-A50EB592052C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1B248B4C-7584-4C04-850A-A50EB592052C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1B248B4C-7584-4C04-850A-A50EB592052C}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -98,12 +111,12 @@ Global
{1B248B4C-7584-4C04-850A-A50EB592052C}.Release|x64.Build.0 = Release|Any CPU
{1B248B4C-7584-4C04-850A-A50EB592052C}.Release|x86.ActiveCfg = Release|Any CPU
{1B248B4C-7584-4C04-850A-A50EB592052C}.Release|x86.Build.0 = Release|Any CPU
- {1B248B4C-7584-4C04-850A-A50EB592052C}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {1B248B4C-7584-4C04-850A-A50EB592052C}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {1B248B4C-7584-4C04-850A-A50EB592052C}.Checked|x64.ActiveCfg = Debug|Any CPU
- {1B248B4C-7584-4C04-850A-A50EB592052C}.Checked|x64.Build.0 = Debug|Any CPU
- {1B248B4C-7584-4C04-850A-A50EB592052C}.Checked|x86.ActiveCfg = Debug|Any CPU
- {1B248B4C-7584-4C04-850A-A50EB592052C}.Checked|x86.Build.0 = Debug|Any CPU
+ {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|x64.Build.0 = Debug|Any CPU
+ {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|x86.Build.0 = Debug|Any CPU
{5BB5F99F-1052-4EB4-B12E-7863805661F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5BB5F99F-1052-4EB4-B12E-7863805661F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5BB5F99F-1052-4EB4-B12E-7863805661F3}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -116,12 +129,12 @@ Global
{5BB5F99F-1052-4EB4-B12E-7863805661F3}.Release|x64.Build.0 = Release|Any CPU
{5BB5F99F-1052-4EB4-B12E-7863805661F3}.Release|x86.ActiveCfg = Release|Any CPU
{5BB5F99F-1052-4EB4-B12E-7863805661F3}.Release|x86.Build.0 = Release|Any CPU
- {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|x64.ActiveCfg = Debug|Any CPU
- {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|x64.Build.0 = Debug|Any CPU
- {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|x86.ActiveCfg = Debug|Any CPU
- {5BB5F99F-1052-4EB4-B12E-7863805661F3}.Checked|x86.Build.0 = Debug|Any CPU
+ {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|x64.Build.0 = Debug|Any CPU
+ {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|x86.Build.0 = Debug|Any CPU
{04BA3E3C-6979-4792-B19E-C797AD607F42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{04BA3E3C-6979-4792-B19E-C797AD607F42}.Debug|Any CPU.Build.0 = Debug|Any CPU
{04BA3E3C-6979-4792-B19E-C797AD607F42}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -134,12 +147,12 @@ Global
{04BA3E3C-6979-4792-B19E-C797AD607F42}.Release|x64.Build.0 = Release|Any CPU
{04BA3E3C-6979-4792-B19E-C797AD607F42}.Release|x86.ActiveCfg = Release|Any CPU
{04BA3E3C-6979-4792-B19E-C797AD607F42}.Release|x86.Build.0 = Release|Any CPU
- {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|x64.ActiveCfg = Debug|Any CPU
- {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|x64.Build.0 = Debug|Any CPU
- {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|x86.ActiveCfg = Debug|Any CPU
- {04BA3E3C-6979-4792-B19E-C797AD607F42}.Checked|x86.Build.0 = Debug|Any CPU
+ {07F19F91-D438-428D-99F0-61DAD87E78BA}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {07F19F91-D438-428D-99F0-61DAD87E78BA}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {07F19F91-D438-428D-99F0-61DAD87E78BA}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {07F19F91-D438-428D-99F0-61DAD87E78BA}.Checked|x64.Build.0 = Debug|Any CPU
+ {07F19F91-D438-428D-99F0-61DAD87E78BA}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {07F19F91-D438-428D-99F0-61DAD87E78BA}.Checked|x86.Build.0 = Debug|Any CPU
{07F19F91-D438-428D-99F0-61DAD87E78BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{07F19F91-D438-428D-99F0-61DAD87E78BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{07F19F91-D438-428D-99F0-61DAD87E78BA}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -152,12 +165,12 @@ Global
{07F19F91-D438-428D-99F0-61DAD87E78BA}.Release|x64.Build.0 = Release|Any CPU
{07F19F91-D438-428D-99F0-61DAD87E78BA}.Release|x86.ActiveCfg = Release|Any CPU
{07F19F91-D438-428D-99F0-61DAD87E78BA}.Release|x86.Build.0 = Release|Any CPU
- {07F19F91-D438-428D-99F0-61DAD87E78BA}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {07F19F91-D438-428D-99F0-61DAD87E78BA}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {07F19F91-D438-428D-99F0-61DAD87E78BA}.Checked|x64.ActiveCfg = Debug|Any CPU
- {07F19F91-D438-428D-99F0-61DAD87E78BA}.Checked|x64.Build.0 = Debug|Any CPU
- {07F19F91-D438-428D-99F0-61DAD87E78BA}.Checked|x86.ActiveCfg = Debug|Any CPU
- {07F19F91-D438-428D-99F0-61DAD87E78BA}.Checked|x86.Build.0 = Debug|Any CPU
+ {768B77B0-EA45-469D-B39E-545EB72F5A43}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {768B77B0-EA45-469D-B39E-545EB72F5A43}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {768B77B0-EA45-469D-B39E-545EB72F5A43}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {768B77B0-EA45-469D-B39E-545EB72F5A43}.Checked|x64.Build.0 = Debug|Any CPU
+ {768B77B0-EA45-469D-B39E-545EB72F5A43}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {768B77B0-EA45-469D-B39E-545EB72F5A43}.Checked|x86.Build.0 = Debug|Any CPU
{768B77B0-EA45-469D-B39E-545EB72F5A43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{768B77B0-EA45-469D-B39E-545EB72F5A43}.Debug|Any CPU.Build.0 = Debug|Any CPU
{768B77B0-EA45-469D-B39E-545EB72F5A43}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -170,12 +183,12 @@ Global
{768B77B0-EA45-469D-B39E-545EB72F5A43}.Release|x64.Build.0 = Release|Any CPU
{768B77B0-EA45-469D-B39E-545EB72F5A43}.Release|x86.ActiveCfg = Release|Any CPU
{768B77B0-EA45-469D-B39E-545EB72F5A43}.Release|x86.Build.0 = Release|Any CPU
- {768B77B0-EA45-469D-B39E-545EB72F5A43}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {768B77B0-EA45-469D-B39E-545EB72F5A43}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {768B77B0-EA45-469D-B39E-545EB72F5A43}.Checked|x64.ActiveCfg = Debug|Any CPU
- {768B77B0-EA45-469D-B39E-545EB72F5A43}.Checked|x64.Build.0 = Debug|Any CPU
- {768B77B0-EA45-469D-B39E-545EB72F5A43}.Checked|x86.ActiveCfg = Debug|Any CPU
- {768B77B0-EA45-469D-B39E-545EB72F5A43}.Checked|x86.Build.0 = Debug|Any CPU
+ {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|x64.Build.0 = Debug|Any CPU
+ {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|x86.Build.0 = Debug|Any CPU
{8671F164-F78C-44FA-93B7-A310F67890FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8671F164-F78C-44FA-93B7-A310F67890FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8671F164-F78C-44FA-93B7-A310F67890FE}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -188,12 +201,12 @@ Global
{8671F164-F78C-44FA-93B7-A310F67890FE}.Release|x64.Build.0 = Release|Any CPU
{8671F164-F78C-44FA-93B7-A310F67890FE}.Release|x86.ActiveCfg = Release|Any CPU
{8671F164-F78C-44FA-93B7-A310F67890FE}.Release|x86.Build.0 = Release|Any CPU
- {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|x64.ActiveCfg = Debug|Any CPU
- {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|x64.Build.0 = Debug|Any CPU
- {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|x86.ActiveCfg = Debug|Any CPU
- {8671F164-F78C-44FA-93B7-A310F67890FE}.Checked|x86.Build.0 = Debug|Any CPU
+ {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|x64.Build.0 = Debug|Any CPU
+ {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|x86.Build.0 = Debug|Any CPU
{4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -206,12 +219,12 @@ Global
{4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Release|x64.Build.0 = Release|Any CPU
{4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Release|x86.ActiveCfg = Release|Any CPU
{4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Release|x86.Build.0 = Release|Any CPU
- {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|x64.ActiveCfg = Debug|Any CPU
- {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|x64.Build.0 = Debug|Any CPU
- {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|x86.ActiveCfg = Debug|Any CPU
- {4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1}.Checked|x86.Build.0 = Debug|Any CPU
+ {79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Checked|x64.Build.0 = Debug|Any CPU
+ {79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Checked|x86.Build.0 = Debug|Any CPU
{79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -224,12 +237,12 @@ Global
{79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Release|x64.Build.0 = Release|Any CPU
{79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Release|x86.ActiveCfg = Release|Any CPU
{79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Release|x86.Build.0 = Release|Any CPU
- {79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Checked|x64.ActiveCfg = Debug|Any CPU
- {79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Checked|x64.Build.0 = Debug|Any CPU
- {79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Checked|x86.ActiveCfg = Debug|Any CPU
- {79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E}.Checked|x86.Build.0 = Debug|Any CPU
+ {57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Checked|x64.Build.0 = Debug|Any CPU
+ {57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Checked|x86.Build.0 = Debug|Any CPU
{57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -242,12 +255,12 @@ Global
{57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Release|x64.Build.0 = Release|Any CPU
{57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Release|x86.ActiveCfg = Release|Any CPU
{57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Release|x86.Build.0 = Release|Any CPU
- {57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Checked|x64.ActiveCfg = Debug|Any CPU
- {57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Checked|x64.Build.0 = Debug|Any CPU
- {57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Checked|x86.ActiveCfg = Debug|Any CPU
- {57A1A6FD-9231-4DFB-8619-F0EDEDA208E3}.Checked|x86.Build.0 = Debug|Any CPU
+ {4B516949-4AD4-44D6-AF86-C2E6058608D5}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {4B516949-4AD4-44D6-AF86-C2E6058608D5}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {4B516949-4AD4-44D6-AF86-C2E6058608D5}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {4B516949-4AD4-44D6-AF86-C2E6058608D5}.Checked|x64.Build.0 = Debug|Any CPU
+ {4B516949-4AD4-44D6-AF86-C2E6058608D5}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {4B516949-4AD4-44D6-AF86-C2E6058608D5}.Checked|x86.Build.0 = Debug|Any CPU
{4B516949-4AD4-44D6-AF86-C2E6058608D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4B516949-4AD4-44D6-AF86-C2E6058608D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B516949-4AD4-44D6-AF86-C2E6058608D5}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -260,12 +273,12 @@ Global
{4B516949-4AD4-44D6-AF86-C2E6058608D5}.Release|x64.Build.0 = Release|Any CPU
{4B516949-4AD4-44D6-AF86-C2E6058608D5}.Release|x86.ActiveCfg = Release|Any CPU
{4B516949-4AD4-44D6-AF86-C2E6058608D5}.Release|x86.Build.0 = Release|Any CPU
- {4B516949-4AD4-44D6-AF86-C2E6058608D5}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {4B516949-4AD4-44D6-AF86-C2E6058608D5}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {4B516949-4AD4-44D6-AF86-C2E6058608D5}.Checked|x64.ActiveCfg = Debug|Any CPU
- {4B516949-4AD4-44D6-AF86-C2E6058608D5}.Checked|x64.Build.0 = Debug|Any CPU
- {4B516949-4AD4-44D6-AF86-C2E6058608D5}.Checked|x86.ActiveCfg = Debug|Any CPU
- {4B516949-4AD4-44D6-AF86-C2E6058608D5}.Checked|x86.Build.0 = Debug|Any CPU
+ {25D66424-2EAF-464D-8460-10C04EDEF3C3}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {25D66424-2EAF-464D-8460-10C04EDEF3C3}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {25D66424-2EAF-464D-8460-10C04EDEF3C3}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {25D66424-2EAF-464D-8460-10C04EDEF3C3}.Checked|x64.Build.0 = Debug|Any CPU
+ {25D66424-2EAF-464D-8460-10C04EDEF3C3}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {25D66424-2EAF-464D-8460-10C04EDEF3C3}.Checked|x86.Build.0 = Debug|Any CPU
{25D66424-2EAF-464D-8460-10C04EDEF3C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25D66424-2EAF-464D-8460-10C04EDEF3C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25D66424-2EAF-464D-8460-10C04EDEF3C3}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -278,12 +291,12 @@ Global
{25D66424-2EAF-464D-8460-10C04EDEF3C3}.Release|x64.Build.0 = Release|Any CPU
{25D66424-2EAF-464D-8460-10C04EDEF3C3}.Release|x86.ActiveCfg = Release|Any CPU
{25D66424-2EAF-464D-8460-10C04EDEF3C3}.Release|x86.Build.0 = Release|Any CPU
- {25D66424-2EAF-464D-8460-10C04EDEF3C3}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {25D66424-2EAF-464D-8460-10C04EDEF3C3}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {25D66424-2EAF-464D-8460-10C04EDEF3C3}.Checked|x64.ActiveCfg = Debug|Any CPU
- {25D66424-2EAF-464D-8460-10C04EDEF3C3}.Checked|x64.Build.0 = Debug|Any CPU
- {25D66424-2EAF-464D-8460-10C04EDEF3C3}.Checked|x86.ActiveCfg = Debug|Any CPU
- {25D66424-2EAF-464D-8460-10C04EDEF3C3}.Checked|x86.Build.0 = Debug|Any CPU
+ {049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Checked|x64.Build.0 = Debug|Any CPU
+ {049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Checked|x86.Build.0 = Debug|Any CPU
{049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -296,12 +309,12 @@ Global
{049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Release|x64.Build.0 = Release|Any CPU
{049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Release|x86.ActiveCfg = Release|Any CPU
{049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Release|x86.Build.0 = Release|Any CPU
- {049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Checked|x64.ActiveCfg = Debug|Any CPU
- {049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Checked|x64.Build.0 = Debug|Any CPU
- {049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Checked|x86.ActiveCfg = Debug|Any CPU
- {049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF}.Checked|x86.Build.0 = Debug|Any CPU
+ {866D295E-424A-4747-9417-CD7746936138}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {866D295E-424A-4747-9417-CD7746936138}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {866D295E-424A-4747-9417-CD7746936138}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {866D295E-424A-4747-9417-CD7746936138}.Checked|x64.Build.0 = Debug|Any CPU
+ {866D295E-424A-4747-9417-CD7746936138}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {866D295E-424A-4747-9417-CD7746936138}.Checked|x86.Build.0 = Debug|Any CPU
{866D295E-424A-4747-9417-CD7746936138}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{866D295E-424A-4747-9417-CD7746936138}.Debug|Any CPU.Build.0 = Debug|Any CPU
{866D295E-424A-4747-9417-CD7746936138}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -314,12 +327,12 @@ Global
{866D295E-424A-4747-9417-CD7746936138}.Release|x64.Build.0 = Release|Any CPU
{866D295E-424A-4747-9417-CD7746936138}.Release|x86.ActiveCfg = Release|Any CPU
{866D295E-424A-4747-9417-CD7746936138}.Release|x86.Build.0 = Release|Any CPU
- {866D295E-424A-4747-9417-CD7746936138}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {866D295E-424A-4747-9417-CD7746936138}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {866D295E-424A-4747-9417-CD7746936138}.Checked|x64.ActiveCfg = Debug|Any CPU
- {866D295E-424A-4747-9417-CD7746936138}.Checked|x64.Build.0 = Debug|Any CPU
- {866D295E-424A-4747-9417-CD7746936138}.Checked|x86.ActiveCfg = Debug|Any CPU
- {866D295E-424A-4747-9417-CD7746936138}.Checked|x86.Build.0 = Debug|Any CPU
+ {D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Checked|x64.Build.0 = Debug|Any CPU
+ {D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Checked|x86.Build.0 = Debug|Any CPU
{D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -332,24 +345,20 @@ Global
{D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Release|x64.Build.0 = Release|Any CPU
{D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Release|x86.ActiveCfg = Release|Any CPU
{D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Release|x86.Build.0 = Release|Any CPU
- {D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
- {D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Checked|Any CPU.Build.0 = Debug|Any CPU
- {D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Checked|x64.ActiveCfg = Debug|Any CPU
- {D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Checked|x64.Build.0 = Debug|Any CPU
- {D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Checked|x86.ActiveCfg = Debug|Any CPU
- {D3A329E3-0FEB-4136-9CB6-B38319B0FFA5}.Checked|x86.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{94B59BA0-491F-4B59-ADFF-A057EC3EC835} = {B1678CCD-95C8-4419-B9F9-14A03061BE4B}
+ {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA} = {FB99AC59-1744-4F12-A4B0-0D54FCA048BF}
{1B248B4C-7584-4C04-850A-A50EB592052C} = {B1678CCD-95C8-4419-B9F9-14A03061BE4B}
+ {5BB5F99F-1052-4EB4-B12E-7863805661F3} = {D893B9AA-57C5-49E3-97B1-12CC62D84307}
{04BA3E3C-6979-4792-B19E-C797AD607F42} = {B1678CCD-95C8-4419-B9F9-14A03061BE4B}
{07F19F91-D438-428D-99F0-61DAD87E78BA} = {B1678CCD-95C8-4419-B9F9-14A03061BE4B}
{768B77B0-EA45-469D-B39E-545EB72F5A43} = {B1678CCD-95C8-4419-B9F9-14A03061BE4B}
+ {8671F164-F78C-44FA-93B7-A310F67890FE} = {D893B9AA-57C5-49E3-97B1-12CC62D84307}
{4FC33B9B-1BCF-4D16-B886-DCA8F2B823C1} = {B1678CCD-95C8-4419-B9F9-14A03061BE4B}
- {1FF4CC8E-49C3-42A0-A6E0-2E5908455FBA} = {FB99AC59-1744-4F12-A4B0-0D54FCA048BF}
{79F7BE0E-01AA-4AFB-B047-CF7C0B38F81E} = {FB99AC59-1744-4F12-A4B0-0D54FCA048BF}
{57A1A6FD-9231-4DFB-8619-F0EDEDA208E3} = {FB99AC59-1744-4F12-A4B0-0D54FCA048BF}
{4B516949-4AD4-44D6-AF86-C2E6058608D5} = {FB99AC59-1744-4F12-A4B0-0D54FCA048BF}
@@ -357,8 +366,6 @@ Global
{049B7FD4-ACEF-4BCD-A7A7-75C9BBEC4EBF} = {FB99AC59-1744-4F12-A4B0-0D54FCA048BF}
{866D295E-424A-4747-9417-CD7746936138} = {FB99AC59-1744-4F12-A4B0-0D54FCA048BF}
{D3A329E3-0FEB-4136-9CB6-B38319B0FFA5} = {FB99AC59-1744-4F12-A4B0-0D54FCA048BF}
- {5BB5F99F-1052-4EB4-B12E-7863805661F3} = {D893B9AA-57C5-49E3-97B1-12CC62D84307}
- {8671F164-F78C-44FA-93B7-A310F67890FE} = {D893B9AA-57C5-49E3-97B1-12CC62D84307}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D4031401-FEB5-4CCF-91C1-38F5646B2BFD}
diff --git a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/AnalyzerReleases.Unshipped.md b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/AnalyzerReleases.Unshipped.md
index 87ac29a463b..05e2158b078 100644
--- a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/AnalyzerReleases.Unshipped.md
+++ b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/AnalyzerReleases.Unshipped.md
@@ -22,3 +22,4 @@ DLLIMPORTGENANALYZER014 | Usage | Error | RefValuePropertyUnsuppor
DLLIMPORTGENANALYZER015 | Interoperability | Disabled | ConvertToGeneratedDllImportAnalyzer
DLLIMPORTGENANALYZER016 | Usage | Error | GenericTypeMustBeClosed
DLLIMPORTGENANALYZER017 | Usage | Warning | GeneratedDllImportContainingTypeMissingModifiers
+DLLIMPORTGENANALYZER018 | Usage | Error | MarshallerGetPinnableReferenceRequiresValueProperty
diff --git a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/AnalyzerDiagnostics.cs b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/AnalyzerDiagnostics.cs
index 4f4d7690fe0..37740545ed1 100644
--- a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/AnalyzerDiagnostics.cs
+++ b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/AnalyzerDiagnostics.cs
@@ -29,6 +29,7 @@ namespace Microsoft.Interop.Analyzers
public const string StackallocConstructorMustHaveStackBufferSizeConstant = Prefix + "012";
public const string RefValuePropertyUnsupported = Prefix + "014";
public const string NativeGenericTypeMustBeClosedOrMatchArity = Prefix + "016";
+ public const string MarshallerGetPinnableReferenceRequiresValueProperty = Prefix + "018";
// GeneratedDllImport
public const string GeneratedDllImportMissingRequiredModifiers = Prefix + "013";
diff --git a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/ManualTypeMarshallingAnalyzer.cs b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/ManualTypeMarshallingAnalyzer.cs
index f975a68c58f..5446b843aea 100644
--- a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/ManualTypeMarshallingAnalyzer.cs
+++ b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Analyzers/ManualTypeMarshallingAnalyzer.cs
@@ -54,7 +54,7 @@ namespace Microsoft.Interop.Analyzers
Category,
DiagnosticSeverity.Error,
isEnabledByDefault: true,
- description: GetResourceString(nameof(Resources.BlittableTypeMustBeBlittableDescription)));
+ description: GetResourceString(nameof(Resources.NativeTypeMustBeBlittableDescription)));
public static readonly DiagnosticDescriptor GetPinnableReferenceReturnTypeBlittableRule =
new DiagnosticDescriptor(
@@ -166,6 +166,16 @@ namespace Microsoft.Interop.Analyzers
isEnabledByDefault: true,
description: GetResourceString(nameof(Resources.NativeGenericTypeMustBeClosedOrMatchArityDescription)));
+ public static readonly DiagnosticDescriptor MarshallerGetPinnableReferenceRequiresValuePropertyRule =
+ new DiagnosticDescriptor(
+ Ids.MarshallerGetPinnableReferenceRequiresValueProperty,
+ "MarshallerGetPinnableReferenceRequiresValueProperty",
+ GetResourceString(nameof(Resources.MarshallerGetPinnableReferenceRequiresValuePropertyMessage)),
+ Category,
+ DiagnosticSeverity.Error,
+ isEnabledByDefault: true,
+ description: GetResourceString(nameof(Resources.MarshallerGetPinnableReferenceRequiresValuePropertyDescription)));
+
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
ImmutableArray.Create(
BlittableTypeMustBeBlittableRule,
@@ -182,7 +192,8 @@ namespace Microsoft.Interop.Analyzers
StackallocMarshallingShouldSupportAllocatingMarshallingFallbackRule,
StackallocConstructorMustHaveStackBufferSizeConstantRule,
RefValuePropertyUnsupportedRule,
- NativeGenericTypeMustBeClosedOrMatchArityRule);
+ NativeGenericTypeMustBeClosedOrMatchArityRule,
+ MarshallerGetPinnableReferenceRequiresValuePropertyRule);
public override void Initialize(AnalysisContext context)
{
@@ -494,6 +505,17 @@ namespace Microsoft.Interop.Analyzers
marshalerType.ToDisplayString()));
}
}
+ else if (ManualTypeMarshallingHelper.FindGetPinnableReference(marshalerType) is IMethodSymbol marshallerGetPinnableReferenceMethod)
+ {
+ // If we don't have a Value property, then we disallow a GetPinnableReference on the marshaler type.
+ // We do this since there is no valid use case that we can think of for a GetPinnableReference on a blittable type
+ // being a requirement to calculate the value of the fields of the same blittable instance,
+ // so we're pre-emptively blocking this until a use case is discovered.
+ context.ReportDiagnostic(
+ marshallerGetPinnableReferenceMethod.CreateDiagnostic(
+ MarshallerGetPinnableReferenceRequiresValuePropertyRule,
+ nativeType.ToDisplayString()));
+ }
if (!nativeType.IsConsideredBlittable())
{
@@ -504,18 +526,11 @@ namespace Microsoft.Interop.Analyzers
type.ToDisplayString()));
}
- // Use a tuple here instead of an anonymous type so we can do the reassignment and pattern matching below.
- var getPinnableReferenceMethods = new
+ if (isNativeMarshallingAttribute && ManualTypeMarshallingHelper.FindGetPinnableReference(type) is IMethodSymbol managedGetPinnableReferenceMethod)
{
- Managed = isNativeMarshallingAttribute ? ManualTypeMarshallingHelper.FindGetPinnableReference(type) : null,
- Marshaler = ManualTypeMarshallingHelper.FindGetPinnableReference(marshalerType)
- };
-
- if (getPinnableReferenceMethods.Managed is not null)
- {
- if (!getPinnableReferenceMethods.Managed.ReturnType.IsConsideredBlittable())
+ if (!managedGetPinnableReferenceMethod.ReturnType.IsConsideredBlittable())
{
- context.ReportDiagnostic(getPinnableReferenceMethods.Managed.CreateDiagnostic(GetPinnableReferenceReturnTypeBlittableRule));
+ context.ReportDiagnostic(managedGetPinnableReferenceMethod.CreateDiagnostic(GetPinnableReferenceReturnTypeBlittableRule));
}
// Validate that our marshaler supports scenarios where GetPinnableReference cannot be used.
if (isNativeMarshallingAttribute && (!hasConstructor || valueProperty is { GetMethod: null }))
@@ -525,23 +540,23 @@ namespace Microsoft.Interop.Analyzers
GetPinnableReferenceShouldSupportAllocatingMarshallingFallbackRule,
type.ToDisplayString()));
}
- }
- if ((getPinnableReferenceMethods.Managed is not null
- || getPinnableReferenceMethods.Marshaler is not null)
- && !valuePropertyIsRefReturn // Ref returns are already reported above as invalid, so don't issue another warning here about them
- && nativeType is not (
+ // If the managed type has a GetPinnableReference method, make sure that the Value getter is also a pointer-sized primitive.
+ // This ensures that marshalling via pinning the managed value and marshalling via the default marshaller will have the same ABI.
+ if (!valuePropertyIsRefReturn // Ref returns are already reported above as invalid, so don't issue another warning here about them
+ && nativeType is not (
IPointerTypeSymbol _ or
{ SpecialType: SpecialType.System_IntPtr } or
{ SpecialType: SpecialType.System_UIntPtr }))
- {
- IMethodSymbol getPinnableReferenceMethodToMention = getPinnableReferenceMethods.Managed ?? getPinnableReferenceMethods.Marshaler!;
+ {
+ IMethodSymbol getPinnableReferenceMethodToMention = managedGetPinnableReferenceMethod;
- context.ReportDiagnostic(
- GetDiagnosticLocations(context, nativeTypeDiagnosticsTargetSymbol, nativeMarshalerAttributeData).CreateDiagnostic(
- NativeTypeMustBePointerSizedRule,
- nativeType.ToDisplayString(),
- getPinnableReferenceMethodToMention.ContainingType.ToDisplayString()));
+ context.ReportDiagnostic(
+ GetDiagnosticLocations(context, nativeTypeDiagnosticsTargetSymbol, nativeMarshalerAttributeData).CreateDiagnostic(
+ NativeTypeMustBePointerSizedRule,
+ nativeType.ToDisplayString(),
+ getPinnableReferenceMethodToMention.ContainingType.ToDisplayString()));
+ }
}
}
diff --git a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/PInvokeStubCodeGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/PInvokeStubCodeGenerator.cs
index 9eb5f6272a6..5da6deb9cc8 100644
--- a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/PInvokeStubCodeGenerator.cs
+++ b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/PInvokeStubCodeGenerator.cs
@@ -488,10 +488,10 @@ namespace Microsoft.Interop
if (fixedStatements.Any())
{
fixedStatements.Reverse();
- invokeStatement = fixedStatements.First().WithStatement(invokeStatement);
+ invokeStatement = fixedStatements.First().AddStatementWithoutEmptyStatements(Block(invokeStatement));
foreach (FixedStatementSyntax fixedStatement in fixedStatements.Skip(1))
{
- invokeStatement = fixedStatement.WithStatement(Block(invokeStatement));
+ invokeStatement = fixedStatement.AddStatementWithoutEmptyStatements(invokeStatement);
}
}
diff --git a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.Designer.cs b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.Designer.cs
index 30ad6508d4f..f44085e2257 100644
--- a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.Designer.cs
+++ b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.Designer.cs
@@ -349,6 +349,24 @@ namespace Microsoft.Interop {
}
/// <summary>
+ /// Looks up a localized string similar to The use cases for &apos;GetPinnableReference&apos; are not applicable in any scenarios where a &apos;Value&apos; property is not also required..
+ /// </summary>
+ internal static string MarshallerGetPinnableReferenceRequiresValuePropertyDescription {
+ get {
+ return ResourceManager.GetString("MarshallerGetPinnableReferenceRequiresValuePropertyDescription", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The &apos;GetPinnableReference&apos; method cannot be provided on the native type &apos;{0}&apos; unless a &apos;Value&apos; property is also provided.
+ /// </summary>
+ internal static string MarshallerGetPinnableReferenceRequiresValuePropertyMessage {
+ get {
+ return ResourceManager.GetString("MarshallerGetPinnableReferenceRequiresValuePropertyMessage", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to The native type &apos;{0}&apos; must be a closed generic so the emitted code can use a specific instantiation..
/// </summary>
internal static string NativeGenericTypeMustBeClosedDescription {
diff --git a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.resx b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.resx
index e66ea89a005..f2acaa98ed1 100644
--- a/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.resx
+++ b/src/libraries/System.Runtime.InteropServices/gen/DllImportGenerator/Resources.resx
@@ -214,6 +214,12 @@
<data name="GetPinnableReferenceShouldSupportAllocatingMarshallingFallbackMessage" xml:space="preserve">
<value>Type '{0}' has a 'GetPinnableReference' method but its native type does not support marshalling in scenarios where pinning is impossible</value>
</data>
+ <data name="MarshallerGetPinnableReferenceRequiresValuePropertyDescription" xml:space="preserve">
+ <value>The use cases for 'GetPinnableReference' are not applicable in any scenarios where a 'Value' property is not also required.</value>
+ </data>
+ <data name="MarshallerGetPinnableReferenceRequiresValuePropertyMessage" xml:space="preserve">
+ <value>The 'GetPinnableReference' method cannot be provided on the native type '{0}' unless a 'Value' property is also provided</value>
+ </data>
<data name="NativeGenericTypeMustBeClosedDescription" xml:space="preserve">
<value>The native type '{0}' must be a closed generic so the emitted code can use a specific instantiation.</value>
</data>
diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs
index 71a0026465a..b653006db9c 100644
--- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs
+++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs
@@ -235,7 +235,10 @@ namespace Microsoft.Interop
{
var subContext = new CustomNativeTypeWithValuePropertyStubContext(context);
- yield return GenerateValuePropertyAssignment(info, context, subContext);
+ if (info.IsManagedReturnPosition || (info.IsByRef && info.RefKind != RefKind.In))
+ {
+ yield return GenerateValuePropertyAssignment(info, context, subContext);
+ }
foreach (StatementSyntax statement in _innerMarshaller.GenerateUnmarshalStatements(info, subContext))
{
@@ -450,7 +453,7 @@ namespace Microsoft.Interop
}
/// <summary>
- /// Marshaller that enables support for a GetPinnableReference method on a native type, with a Value property fallback.
+ /// Marshaller that calls the GetPinnableReference method on the marshaller value and enables support for the Value property.
/// </summary>
internal sealed class PinnableMarshallerTypeMarshalling : ICustomNativeTypeMarshallingStrategy
{
@@ -482,7 +485,7 @@ namespace Microsoft.Interop
{
var subContext = new CustomNativeTypeWithValuePropertyStubContext(context);
- if (!CanPinMarshaller(info, context) && !context.AdditionalTemporaryStateLivesAcrossStages)
+ if (!context.AdditionalTemporaryStateLivesAcrossStages)
{
// <marshalerIdentifier>.Value = <nativeIdentifier>;
yield return GenerateValuePropertyAssignment(info, context, subContext);
@@ -503,35 +506,34 @@ namespace Microsoft.Interop
}
if (!CanPinMarshaller(info, context))
- {
- // <nativeIdentifier> = <marshalerIdentifier>.Value;
- yield return ExpressionStatement(
- AssignmentExpression(
- SyntaxKind.SimpleAssignmentExpression,
- IdentifierName(context.GetIdentifiers(info).native),
- MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
- IdentifierName(subContext.GetIdentifiers(info).native),
- IdentifierName(ManualTypeMarshallingHelper.ValuePropertyName))));
- }
+ yield return GenerateNativeAssignmentFromValueProperty(info, context, subContext);
+ }
+
+ private static StatementSyntax GenerateNativeAssignmentFromValueProperty(TypePositionInfo info, StubCodeContext context, CustomNativeTypeWithValuePropertyStubContext subContext)
+ {
+ // <nativeIdentifier> = <marshalerIdentifier>.Value;
+ return ExpressionStatement(
+ AssignmentExpression(
+ SyntaxKind.SimpleAssignmentExpression,
+ IdentifierName(context.GetIdentifiers(info).native),
+ MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
+ IdentifierName(subContext.GetIdentifiers(info).native),
+ IdentifierName(ManualTypeMarshallingHelper.ValuePropertyName))));
}
public IEnumerable<StatementSyntax> GeneratePinStatements(TypePositionInfo info, StubCodeContext context)
{
- // fixed (<_nativeTypeSyntax> <nativeIdentifier> = &<marshalerIdentifier>)
+ // fixed (<_nativeTypeSyntax> <ignoredIdentifier> = &<marshalerIdentifier>)
+ // <assignment to Value property>
var subContext = new CustomNativeTypeWithValuePropertyStubContext(context);
yield return FixedStatement(
VariableDeclaration(
_valuePropertyType,
SingletonSeparatedList(
- VariableDeclarator(context.GetIdentifiers(info).native)
+ VariableDeclarator(Identifier(context.GetAdditionalIdentifier(info, "ignored")))
.WithInitializer(EqualsValueClause(
- PrefixUnaryExpression(SyntaxKind.AddressOfExpression,
- InvocationExpression(
- MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
- IdentifierName(subContext.GetIdentifiers(info).native),
- IdentifierName(ManualTypeMarshallingHelper.GetPinnableReferenceName)),
- ArgumentList())))))),
- EmptyStatement());
+ IdentifierName(subContext.GetIdentifiers(info).native))))),
+ GenerateNativeAssignmentFromValueProperty(info, context, subContext));
}
public IEnumerable<StatementSyntax> GenerateSetupStatements(TypePositionInfo info, StubCodeContext context)
@@ -566,7 +568,7 @@ namespace Microsoft.Interop
{
var subContext = new CustomNativeTypeWithValuePropertyStubContext(context);
- if (!CanPinMarshaller(info, context))
+ if (info.IsManagedReturnPosition || (info.IsByRef && info.RefKind != RefKind.In))
{
// <marshalerIdentifier>.Value = <nativeIdentifier>;
yield return GenerateValuePropertyAssignment(info, context, subContext);
@@ -586,10 +588,6 @@ namespace Microsoft.Interop
public bool UsesNativeIdentifier(TypePositionInfo info, StubCodeContext context)
{
- if (CanPinMarshaller(info, context))
- {
- return false;
- }
return _innerMarshaller.UsesNativeIdentifier(info, context);
}
}
diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SyntaxExtensions.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SyntaxExtensions.cs
new file mode 100644
index 00000000000..1b56c2000e7
--- /dev/null
+++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SyntaxExtensions.cs
@@ -0,0 +1,33 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace Microsoft.Interop
+{
+ public static class SyntaxExtensions
+ {
+ public static FixedStatementSyntax AddStatementWithoutEmptyStatements(this FixedStatementSyntax fixedStatement, StatementSyntax childStatement)
+ {
+ if (fixedStatement.Statement.IsKind(SyntaxKind.EmptyStatement))
+ {
+ return fixedStatement.WithStatement(childStatement);
+ }
+ if (fixedStatement.Statement.IsKind(SyntaxKind.Block))
+ {
+ var block = (BlockSyntax)fixedStatement.Statement;
+ if (block.Statements.Count == 0)
+ {
+ return fixedStatement.WithStatement(childStatement);
+ }
+ return fixedStatement.WithStatement(block.AddStatements(childStatement));
+ }
+ return fixedStatement.WithStatement(SyntaxFactory.Block(fixedStatement.Statement, childStatement));
+ }
+ }
+}
diff --git a/src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/SpanMarshallers.cs b/src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/SpanMarshallers.cs
index 453259feeda..d5543df3c88 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/SpanMarshallers.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/Ancillary.Interop/SpanMarshallers.cs
@@ -20,20 +20,8 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling
}
public ReadOnlySpanMarshaller(ReadOnlySpan<T> managed, int sizeOfNativeElement)
+ :this(managed, Span<byte>.Empty, sizeOfNativeElement)
{
- _allocatedMemory = default;
- _sizeOfNativeElement = sizeOfNativeElement;
- if (managed.Length == 0)
- {
- _managedSpan = default;
- NativeValueStorage = default;
- return;
- }
- _managedSpan = managed;
- _sizeOfNativeElement = sizeOfNativeElement;
- int spaceToAllocate = managed.Length * sizeOfNativeElement;
- _allocatedMemory = Marshal.AllocCoTaskMem(spaceToAllocate);
- NativeValueStorage = new Span<byte>((void*)_allocatedMemory, spaceToAllocate);
}
public ReadOnlySpanMarshaller(ReadOnlySpan<T> managed, Span<byte> stackSpace, int sizeOfNativeElement)
@@ -81,8 +69,7 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling
{
get
{
- Debug.Assert(_managedSpan.IsEmpty || _allocatedMemory != IntPtr.Zero);
- return (byte*)_allocatedMemory;
+ return (byte*)Unsafe.AsPointer(ref GetPinnableReference());
}
set
{
@@ -222,7 +209,7 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling
{
if (_inner.ManagedValues.Length == 0)
{
- return (byte*)0x1;
+ return (byte*)0xa5a5a5a5;
}
return _inner.Value;
}
@@ -293,7 +280,7 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling
{
if (_inner.ManagedValues.Length == 0)
{
- return (byte*)0x1;
+ return (byte*)0xa5a5a5a5;
}
return _inner.Value;
}
@@ -369,8 +356,11 @@ namespace System.Runtime.InteropServices.GeneratedMarshalling
{
get
{
- Debug.Assert(_data.IsEmpty || _allocatedMemory != null);
- return _allocatedMemory;
+ if (_allocatedMemory != null)
+ {
+ return _allocatedMemory;
+ }
+ return (T*)Unsafe.AsPointer(ref GetPinnableReference());
}
set
{
diff --git a/src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/ManualTypeMarshallingAnalyzerTests.cs b/src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/ManualTypeMarshallingAnalyzerTests.cs
index 2938fa35d31..2a7d42b2d63 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/ManualTypeMarshallingAnalyzerTests.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/DllImportGenerator.UnitTests/ManualTypeMarshallingAnalyzerTests.cs
@@ -455,6 +455,70 @@ unsafe struct Native
}
[ConditionalFact]
+ public async Task NonBlittableMarshallerGetPinnableReferenceReturnType_DoesNotReportDiagnostic()
+ {
+ string source = @"
+using System;
+using System.Runtime.InteropServices;
+
+[NativeMarshalling(typeof(Native))]
+class S
+{
+ public char c;
+}
+
+unsafe struct Native
+{
+ private IntPtr value;
+
+ public Native(S s)
+ {
+ value = IntPtr.Zero;
+ }
+
+ public ref char GetPinnableReference() => ref System.Runtime.CompilerServices.Unsafe.NullRef<char>();
+
+ public S ToManaged() => new S();
+
+ public IntPtr Value { get => IntPtr.Zero; set {} }
+}";
+
+ await VerifyCS.VerifyAnalyzerAsync(source);
+ }
+
+ [ConditionalFact]
+ public async Task BlittableMarshallerGetPinnableReferenceReturnType_DoesNotReportDiagnostic()
+ {
+ string source = @"
+using System;
+using System.Runtime.InteropServices;
+
+[NativeMarshalling(typeof(Native))]
+class S
+{
+ public byte c;
+}
+
+unsafe struct Native
+{
+ private IntPtr value;
+
+ public Native(S s) : this()
+ {
+ value = IntPtr.Zero;
+ }
+
+ public S ToManaged() => new S();
+
+ public ref byte GetPinnableReference() => ref System.Runtime.CompilerServices.Unsafe.NullRef<byte>();
+
+ public IntPtr Value { get => IntPtr.Zero; set {} }
+}";
+
+ await VerifyCS.VerifyAnalyzerAsync(source);
+ }
+
+ [ConditionalFact]
public async Task TypeWithGetPinnableReferenceNonPointerReturnType_ReportsDiagnostic()
{
string source = @"
@@ -520,7 +584,7 @@ unsafe struct Native
}
[ConditionalFact]
- public async Task TypeWithGetPinnableReferenceByRefReturnType_ReportsDiagnostic()
+ public async Task TypeWithGetPinnableReferenceByRefValuePropertyType_ReportsDiagnostic()
{
string source = @"
using System;
@@ -551,7 +615,7 @@ unsafe struct Native
}
[ConditionalFact]
- public async Task NativeTypeWithGetPinnableReferenceByRefReturnType_ReportsDiagnostic()
+ public async Task NativeTypeWithGetPinnableReferenceByRefValuePropertyType_ReportsDiagnostic()
{
string source = @"
using System;
@@ -582,6 +646,67 @@ unsafe struct Native
}
[ConditionalFact]
+ public async Task NativeTypeWithGetPinnableReferenceNoValueProperty_ReportsDiagnostic()
+ {
+ string source = @"
+using System;
+using System.Runtime.InteropServices;
+
+[NativeMarshalling(typeof(Native))]
+class S
+{
+ public byte c;
+}
+
+[BlittableType]
+unsafe struct Native
+{
+ private byte value;
+
+ public Native(S s) : this()
+ {
+ value = s.c;
+ }
+
+ public ref byte {|#0:GetPinnableReference|}() => ref System.Runtime.CompilerServices.Unsafe.NullRef<byte>();
+}";
+
+ await VerifyCS.VerifyAnalyzerAsync(source,
+ VerifyCS.Diagnostic(MarshallerGetPinnableReferenceRequiresValuePropertyRule).WithLocation(0).WithArguments("Native"));
+ }
+
+ [ConditionalFact]
+ public async Task NativeTypeWithGetPinnableReferenceWithNonPointerValueProperty_DoesNotReportDiagnostic()
+ {
+ string source = @"
+using System;
+using System.Runtime.InteropServices;
+
+[NativeMarshalling(typeof(Native))]
+class S
+{
+ public byte c;
+}
+
+[BlittableType]
+unsafe struct Native
+{
+ private byte value;
+
+ public Native(S s) : this()
+ {
+ value = s.c;
+ }
+
+ public ref byte GetPinnableReference() => ref System.Runtime.CompilerServices.Unsafe.NullRef<byte>();
+
+ public int Value { get; set; }
+}";
+
+ await VerifyCS.VerifyAnalyzerAsync(source);
+ }
+
+ [ConditionalFact]
public async Task BlittableValueTypeWithNoFields_DoesNotReportDiagnostic()
{
string source = @"
diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs
index 5d46f83e845..4969c546594 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SharedTypes
@@ -121,44 +122,42 @@ namespace SharedTypes
public unsafe ref struct Utf16StringMarshaler
{
- private ushort* ptr;
+ private ushort* allocated;
private Span<ushort> span;
+ private bool isNullString;
public Utf16StringMarshaler(string str)
+ : this(str, default(Span<byte>))
{
- ptr = str is null ? null : (ushort*)Marshal.StringToCoTaskMemUni(str);
- span = default;
}
public Utf16StringMarshaler(string str, Span<byte> buffer)
{
+ isNullString = false;
if (str is null)
{
- ptr = null;
+ allocated = null;
span = default;
+ isNullString = true;
}
- else if ((str.Length + 1) < StackBufferSize)
+ else if ((str.Length + 1) < buffer.Length)
{
span = MemoryMarshal.Cast<byte, ushort>(buffer);
str.AsSpan().CopyTo(MemoryMarshal.Cast<byte, char>(buffer));
// Supplied memory is in an undefined state so ensure
// there is a trailing null in the buffer.
span[str.Length] = '\0';
- ptr = null;
+ allocated = null;
}
else
{
- span = default;
- ptr = (ushort*)Marshal.StringToCoTaskMemUni(str);
+ allocated = (ushort*)Marshal.StringToCoTaskMemUni(str);
+ span = new Span<ushort>(allocated, str.Length + 1);
}
}
public ref ushort GetPinnableReference()
{
- if (ptr != null)
- {
- return ref *ptr;
- }
return ref span.GetPinnableReference();
}
@@ -166,46 +165,37 @@ namespace SharedTypes
{
get
{
- if (ptr == null && span != default)
- {
- throw new InvalidOperationException();
- }
- return ptr;
+ return (ushort*)Unsafe.AsPointer(ref GetPinnableReference());
}
set
{
- ptr = value;
- span = default;
+ allocated = value;
+ span = new Span<ushort>(value, value == null ? 0 : FindStringLength(value));
+ isNullString = value == null;
+
+ static int FindStringLength(ushort* ptr)
+ {
+ // Implemented similarly to string.wcslen as we can't access that outside of CoreLib
+ var searchSpace = new Span<ushort>(ptr, int.MaxValue);
+ return searchSpace.IndexOf((ushort)0);
+ }
}
}
public string ToManaged()
{
- if (ptr == null && span == default)
- {
- return null;
- }
- else if (ptr != null)
- {
- return Marshal.PtrToStringUni((IntPtr)ptr);
- }
- else
- {
- return MemoryMarshal.Cast<ushort, char>(span).ToString();
- }
+ return isNullString ? null : MemoryMarshal.Cast<ushort, char>(span).ToString();
}
public void FreeNative()
{
- if (ptr != null)
- {
- Marshal.FreeCoTaskMem((IntPtr)ptr);
- }
+ Marshal.FreeCoTaskMem((IntPtr)allocated);
}
public const int StackBufferSize = 0x100;
}
+
[NativeMarshalling(typeof(IntStructWrapperNative))]
public struct IntStructWrapper
{
@@ -237,21 +227,8 @@ namespace SharedTypes
}
public ListMarshaller(List<T> managed, int sizeOfNativeElement)
+ :this(managed, Span<byte>.Empty, sizeOfNativeElement)
{
- allocatedMemory = default;
- this.sizeOfNativeElement = sizeOfNativeElement;
- if (managed is null)
- {
- managedList = null;
- NativeValueStorage = default;
- return;
- }
- managedList = managed;
- this.sizeOfNativeElement = sizeOfNativeElement;
- // Always allocate at least one byte when the array is zero-length.
- int spaceToAllocate = Math.Max(managed.Count * sizeOfNativeElement, 1);
- allocatedMemory = Marshal.AllocCoTaskMem(spaceToAllocate);
- NativeValueStorage = new Span<byte>((void*)allocatedMemory, spaceToAllocate);
}
public ListMarshaller(List<T> managed, Span<byte> stackSpace, int sizeOfNativeElement)
@@ -265,7 +242,7 @@ namespace SharedTypes
return;
}
managedList = managed;
- // Always allocate at least one byte when the array is zero-length.
+ // Always allocate at least one byte when the list is zero-length.
int spaceToAllocate = Math.Max(managed.Count * sizeOfNativeElement, 1);
if (spaceToAllocate <= stackSpace.Length)
{
@@ -304,8 +281,7 @@ namespace SharedTypes
{
get
{
- Debug.Assert(managedList is null || allocatedMemory != IntPtr.Zero);
- return (byte*)allocatedMemory;
+ return (byte*)Unsafe.AsPointer(ref GetPinnableReference());
}
set
{
@@ -326,10 +302,7 @@ namespace SharedTypes
public void FreeNative()
{
- if (allocatedMemory != IntPtr.Zero)
- {
- Marshal.FreeCoTaskMem(allocatedMemory);
- }
+ Marshal.FreeCoTaskMem(allocatedMemory);
}
}
}