mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-08 11:37:04 +09:00
Update design and expose new attributes for the CustomTypeMarshaller support (#71682)
This commit is contained in:
parent
a6d5f6b161
commit
c99b5b067c
31 changed files with 415 additions and 381 deletions
|
@ -154,9 +154,6 @@ csharp_space_between_square_brackets = false
|
||||||
# License header
|
# License header
|
||||||
file_header_template = Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.
|
file_header_template = Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
|
||||||
# Marshaller type must have CustomTypeMarshallerAttribute attribute
|
|
||||||
dotnet_diagnostic.SYSLIB1056.severity = silent
|
|
||||||
|
|
||||||
# C++ Files
|
# C++ Files
|
||||||
[*.{cpp,h,in}]
|
[*.{cpp,h,in}]
|
||||||
curly_bracket_next_line = true
|
curly_bracket_next_line = true
|
||||||
|
|
|
@ -97,114 +97,94 @@ namespace System.Runtime.InteropServices.Marshalling;
|
||||||
- Ref = In | Out,
|
- Ref = In | Out,
|
||||||
- }
|
- }
|
||||||
|
|
||||||
|
+
|
||||||
|
+
|
||||||
+ /// <summary>
|
+ /// <summary>
|
||||||
+ /// Define features for a custom type marshaller.
|
+ /// An enumeration representing the different marshalling scenarios in our marshalling model.
|
||||||
+ /// </summary>
|
+ /// </summary>
|
||||||
+ [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class)]
|
+ public enum MarshalMode
|
||||||
+ public sealed class CustomTypeMarshallerFeaturesAttribute : Attribute
|
|
||||||
+ {
|
+ {
|
||||||
+ /// <summary>
|
+ /// <summary>
|
||||||
+ /// Desired caller buffer size for the marshaller.
|
+ /// All scenarios. A marshaller specified with this scenario will be used if there is not a specific
|
||||||
|
+ /// marshaller specified for a given usage scenario.
|
||||||
+ /// </summary>
|
+ /// </summary>
|
||||||
+ public int BufferSize { get; set; }
|
+ Default,
|
||||||
|
+ /// <summary>
|
||||||
|
+ /// By-value and <c>in</c> parameters in managed-to-unmanaged scenarios, like P/Invoke.
|
||||||
|
+ /// </summary>
|
||||||
|
+ ManagedToUnmanagedIn,
|
||||||
|
+ /// <summary>
|
||||||
|
+ /// <c>ref</c> parameters in managed-to-unmanaged scenarios, like P/Invoke.
|
||||||
|
+ /// </summary>
|
||||||
|
+ ManagedToUnmanagedRef,
|
||||||
|
+ /// <summary>
|
||||||
|
+ /// <c>out</c> parameters in managed-to-unmanaged scenarios, like P/Invoke.
|
||||||
|
+ /// </summary>
|
||||||
|
+ ManagedToUnmanagedOut,
|
||||||
|
+ /// <summary>
|
||||||
|
+ /// By-value and <c>in</c> parameters in unmanaged-to-managed scenarios, like Reverse P/Invoke.
|
||||||
|
+ /// </summary>
|
||||||
|
+ UnmanagedToManagedIn,
|
||||||
|
+ /// <summary>
|
||||||
|
+ /// <c>ref</c> parameters in unmanaged-to-managed scenarios, like Reverse P/Invoke.
|
||||||
|
+ /// </summary>
|
||||||
|
+ UnmanagedToManagedRef,
|
||||||
|
+ /// <summary>
|
||||||
|
+ /// <c>out</c> parameters in unmanaged-to-managed scenarios, like Reverse P/Invoke.
|
||||||
|
+ /// </summary>
|
||||||
|
+ UnmanagedToManagedOut,
|
||||||
|
+ /// <summary>
|
||||||
|
+ /// Elements of arrays passed with <c>in</c> or by-value in interop scenarios.
|
||||||
|
+ /// </summary>
|
||||||
|
+ ElementIn,
|
||||||
|
+ /// <summary>
|
||||||
|
+ /// Elements of arrays passed with <c>ref</c> or passed by-value with both <see cref="InAttribute"/> and <see cref="OutAttribute" /> in interop scenarios.
|
||||||
|
+ /// </summary>
|
||||||
|
+ ElementRef,
|
||||||
|
+ /// <summary>
|
||||||
|
+ /// Elements of arrays passed with <c>out</c> or passed by-value with only <see cref="OutAttribute" /> in interop scenarios.
|
||||||
|
+ /// </summary>
|
||||||
|
+ ElementOut
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+
|
|
||||||
+ /// <summary>
|
+ /// <summary>
|
||||||
+ /// Base class attribute for custom marshaller attributes.
|
+ /// Attribute to indicate an entry point type for defining a marshaller.
|
||||||
+ /// </summary>
|
+ /// </summary>
|
||||||
+ /// <remarks>
|
+ [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true)]
|
||||||
+ /// Use a base class here to allow doing ManagedToUnmanagedMarshallersAttribute.GenericPlaceholder, etc. without having 3 + separate placeholder types.
|
+ public sealed class CustomMarshallerAttribute : Attribute
|
||||||
+ /// For the following attribute types, any marshaller types that are provided will be validated by an analyzer to have the + correct members to prevent
|
|
||||||
+ /// developers from accidentally typoing a member like Free() and causing memory leaks.
|
|
||||||
+ /// </remarks>
|
|
||||||
+ public abstract class CustomUnmanagedTypeMarshallersAttributeBase : Attribute
|
|
||||||
+ {
|
+ {
|
||||||
+ /// <summary>
|
+ /// <summary>
|
||||||
|
+ /// Create a <see cref="CustomMarshallerAttribute"/> instance.
|
||||||
|
+ /// </summary>
|
||||||
|
+ /// <param name="managedType">Managed type to marshal.</param>
|
||||||
|
+ /// <param name="marshalMode">Marshalling mode.</param>
|
||||||
|
+ /// <param name="marshallerType">Type used for marshalling.</param>
|
||||||
|
+ public CustomMarshallerAttribute(Type managedType, MarshalMode marshalMode, Type marshallerType)
|
||||||
|
+ {
|
||||||
|
+ ManagedType = managedType;
|
||||||
|
+ MarshalMode = marshalMode;
|
||||||
|
+ MarshallerType = marshallerType;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public Type ManagedType { get; }
|
||||||
|
+
|
||||||
|
+ public MarshalMode MarshalMode { get; }
|
||||||
|
+
|
||||||
|
+ public Type MarshallerType { get; }
|
||||||
|
+
|
||||||
|
+ /// <summary>
|
||||||
+ /// Placeholder type for generic parameter
|
+ /// Placeholder type for generic parameter
|
||||||
+ /// </summary>
|
+ /// </summary>
|
||||||
+ public sealed class GenericPlaceholder { }
|
+ public struct GenericPlaceholder
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /// <summary>
|
|
||||||
+ /// Specify marshallers used in the managed to unmanaged direction (that is, P/Invoke)
|
|
||||||
+ /// </summary>
|
|
||||||
+ [AttributeUsage(AttributeTargets.Class)]
|
|
||||||
+ public sealed class ManagedToUnmanagedMarshallersAttribute : CustomUnmanagedTypeMarshallersAttributeBase
|
|
||||||
+ {
|
+ {
|
||||||
+ /// <summary>
|
+ }
|
||||||
+ /// Create instance of <see cref="ManagedToUnmanagedMarshallersAttribute"/>.
|
|
||||||
+ /// </summary>
|
|
||||||
+ /// <param name="managedType">Managed type to marshal</param>
|
|
||||||
+ public ManagedToUnmanagedMarshallersAttribute(Type managedType) { }
|
|
||||||
+
|
|
||||||
+ /// <summary>
|
|
||||||
+ /// Marshaller to use when a parameter of the managed type is passed by-value or with the <c>in</c> keyword.
|
|
||||||
+ /// </summary>
|
|
||||||
+ public Type? InMarshaller { get; set; }
|
|
||||||
+
|
|
||||||
+ /// <summary>
|
|
||||||
+ /// Marshaller to use when a parameter of the managed type is passed by-value or with the <c>ref</c> keyword.
|
|
||||||
+ /// </summary>
|
|
||||||
+ public Type? RefMarshaller { get; set; }
|
|
||||||
+
|
|
||||||
+ /// <summary>
|
|
||||||
+ /// Marshaller to use when a parameter of the managed type is passed by-value or with the <c>out</c> keyword.
|
|
||||||
+ /// </summary>
|
|
||||||
+ public Type? OutMarshaller { get; set; }
|
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ /// <summary>
|
+ /// <summary>
|
||||||
+ /// Specify marshallers used in the unmanaged to managed direction (that is, Reverse P/Invoke)
|
+ /// Specifies that this marshaller entry-point type is a contiguous collection marshaller.
|
||||||
+ /// </summary>
|
+ /// </summary>
|
||||||
+ [AttributeUsage(AttributeTargets.Class)]
|
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
||||||
+ public sealed class UnmanagedToManagedMarshallersAttribute : CustomUnmanagedTypeMarshallersAttributeBase
|
+ public sealed class ContiguousCollectionMarshallerAttribute : Attribute
|
||||||
+ {
|
|
||||||
+ /// <summary>
|
|
||||||
+ /// Create instance of <see cref="UnmanagedToManagedMarshallersAttribute"/>.
|
|
||||||
+ /// </summary>
|
|
||||||
+ /// <param name="managedType">Managed type to marshal</param>
|
|
||||||
+ public UnmanagedToManagedMarshallersAttribute(Type managedType) { }
|
|
||||||
+
|
|
||||||
+ /// <summary>
|
|
||||||
+ /// Marshaller to use when a parameter of the managed type is passed by-value or with the <c>in</c> keyword.
|
|
||||||
+ /// </summary>
|
|
||||||
+ public Type? InMarshaller { get; set; }
|
|
||||||
+
|
|
||||||
+ /// <summary>
|
|
||||||
+ /// Marshaller to use when a parameter of the managed type is passed by-value or with the <c>ref</c> keyword.
|
|
||||||
+ /// </summary>
|
|
||||||
+ public Type? RefMarshaller { get; set; }
|
|
||||||
+
|
|
||||||
+ /// <summary>
|
|
||||||
+ /// Marshaller to use when a parameter of the managed type is passed by-value or with the <c>out</c> keyword.
|
|
||||||
+ /// </summary>
|
|
||||||
+ public Type? OutMarshaller { get; set; }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /// <summary>
|
|
||||||
+ /// Specify marshaller for array-element marshalling and default struct field marshalling.
|
|
||||||
+ /// </summary>
|
|
||||||
+ [AttributeUsage(AttributeTargets.Class)]
|
|
||||||
+ public sealed class ElementMarshallerAttribute : CustomUnmanagedTypeMarshallersAttributeBase
|
|
||||||
+ {
|
|
||||||
+ /// <summary>
|
|
||||||
+ /// Create instance of <see cref="ElementMarshallerAttribute"/>.
|
|
||||||
+ /// </summary>
|
|
||||||
+ /// <param name="managedType">Managed type to marshal</param>
|
|
||||||
+ /// <param name="elementMarshaller">Marshaller type to use for marshalling <paramref name="managedType"/>.</param>
|
|
||||||
+ public ElementMarshallerAttribute(Type managedType, Type elementMarshaller) { }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /// <summary>
|
|
||||||
+ /// Specifies that a particular generic parameter is the collection element's unmanaged type.
|
|
||||||
+ /// </summary>
|
|
||||||
+ /// <remarks>
|
|
||||||
+ /// If this attribute is provided on a generic parameter of a marshaller, then the generator will assume
|
|
||||||
+ /// that it is a linear collection marshaller.
|
|
||||||
+ /// </remarks>
|
|
||||||
+ [AttributeUsage(AttributeTargets.GenericParameter)]
|
|
||||||
+ public sealed class ElementUnmanagedTypeAttribute : Attribute
|
|
||||||
+ {
|
+ {
|
||||||
+ }
|
+ }
|
||||||
```
|
```
|
||||||
|
@ -264,9 +244,9 @@ The element type of the `Span` for the caller-allocated buffer can be any type t
|
||||||
[UnmanagedToManagedMarshallers(typeof(TManaged<,,,...>), OutMarshaller = typeof(ManagedToNative))]
|
[UnmanagedToManagedMarshallers(typeof(TManaged<,,,...>), OutMarshaller = typeof(ManagedToNative))]
|
||||||
static class TMarshaller<T, U, V...>
|
static class TMarshaller<T, U, V...>
|
||||||
{
|
{
|
||||||
[CustomTypeMarshallerFeatures(BufferSize = 0x200)]
|
|
||||||
public static class ManagedToNative
|
public static class ManagedToNative
|
||||||
{
|
{
|
||||||
|
public static int BufferSize { get; }
|
||||||
public static TNative ConvertToUnmanaged(TManaged managed, Span<byte> callerAllocatedBuffer); // Can throw exceptions
|
public static TNative ConvertToUnmanaged(TManaged managed, Span<byte> callerAllocatedBuffer); // Can throw exceptions
|
||||||
|
|
||||||
public static void Free(TNative unmanaged); // Optional. Should not throw exceptions
|
public static void Free(TNative unmanaged); // Optional. Should not throw exceptions
|
||||||
|
@ -294,7 +274,7 @@ static class TMarshaller<T, U, V...>
|
||||||
|
|
||||||
### Stateless Unmanaged->Managed with Guaranteed Unmarshalling
|
### Stateless Unmanaged->Managed with Guaranteed Unmarshalling
|
||||||
|
|
||||||
This shape directs the generator to emit the `ConvertToManagedGuaranteed` call in the "GuaranteedUnmarshal" phase of marshalling.
|
This shape directs the generator to emit the `ConvertToManagedFinally` call in the "GuaranteedUnmarshal" phase of marshalling.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TManaged<,,,...>), OutMarshaller = typeof(NativeToManaged))]
|
[ManagedToUnmanagedMarshallers(typeof(TManaged<,,,...>), OutMarshaller = typeof(NativeToManaged))]
|
||||||
|
@ -303,7 +283,7 @@ static class TMarshaller<T, U, V...>
|
||||||
{
|
{
|
||||||
public static class NativeToManaged
|
public static class NativeToManaged
|
||||||
{
|
{
|
||||||
public static TManaged ConvertToManagedGuaranteed(TNative unmanaged); // Should not throw exceptions
|
public static TManaged ConvertToManagedFinally(TNative unmanaged); // Should not throw exceptions
|
||||||
|
|
||||||
public static void Free(TNative unmanaged); // Optional. Should not throw exceptions
|
public static void Free(TNative unmanaged); // Optional. Should not throw exceptions
|
||||||
}
|
}
|
||||||
|
@ -347,7 +327,7 @@ static class TMarshaller<T, U, V...>
|
||||||
|
|
||||||
public TNative ToUnmanaged(); // Can throw exceptions.
|
public TNative ToUnmanaged(); // Can throw exceptions.
|
||||||
|
|
||||||
public void NotifyInvokeSucceeded(); // Optional. Should not throw exceptions.
|
public void OnInvoked(); // Optional. Should not throw exceptions.
|
||||||
|
|
||||||
public void Free(); // Should not throw exceptions.
|
public void Free(); // Should not throw exceptions.
|
||||||
}
|
}
|
||||||
|
@ -363,9 +343,9 @@ The element type of the `Span` for the caller-allocated buffer can be any type t
|
||||||
[UnmanagedToManagedMarshallers(typeof(TManaged<,,,...>), OutMarshaller = typeof(ManagedToNative))]
|
[UnmanagedToManagedMarshallers(typeof(TManaged<,,,...>), OutMarshaller = typeof(ManagedToNative))]
|
||||||
static class TMarshaller<T, U, V...>
|
static class TMarshaller<T, U, V...>
|
||||||
{
|
{
|
||||||
[CustomTypeMarshallerFeatures(BufferSize = 0x200)]
|
|
||||||
public struct ManagedToNative // Can be ref struct
|
public struct ManagedToNative // Can be ref struct
|
||||||
{
|
{
|
||||||
|
public static int BufferSize { get; }
|
||||||
public ManagedToNative(); // Optional, can throw exceptions.
|
public ManagedToNative(); // Optional, can throw exceptions.
|
||||||
|
|
||||||
public void FromManaged(TManaged managed, Span<byte> buffer); // Can throw exceptions.
|
public void FromManaged(TManaged managed, Span<byte> buffer); // Can throw exceptions.
|
||||||
|
@ -376,7 +356,7 @@ static class TMarshaller<T, U, V...>
|
||||||
|
|
||||||
public TNative ToUnmanaged(); // Can throw exceptions.
|
public TNative ToUnmanaged(); // Can throw exceptions.
|
||||||
|
|
||||||
public void NotifyInvokeSucceeded(); // Optional. Should not throw exceptions.
|
public void OnInvoked(); // Optional. Should not throw exceptions.
|
||||||
|
|
||||||
public void Free(); // Should not throw exceptions.
|
public void Free(); // Should not throw exceptions.
|
||||||
}
|
}
|
||||||
|
@ -418,7 +398,7 @@ static class TMarshaller<T, U, V...>
|
||||||
|
|
||||||
public void FromUnmanaged(TNative native); // Should not throw exceptions.
|
public void FromUnmanaged(TNative native); // Should not throw exceptions.
|
||||||
|
|
||||||
public TManaged ToManagedGuaranteed(); // Should not throw exceptions.
|
public TManaged ToManagedFinally(); // Should not throw exceptions.
|
||||||
|
|
||||||
public void Free(); // Should not throw exceptions.
|
public void Free(); // Should not throw exceptions.
|
||||||
}
|
}
|
||||||
|
@ -455,7 +435,7 @@ struct TCollection<T, U, V...>
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
A collection marshaller for a managed type will have similar generics handling as the value marshaller case; however, there is one difference. A collection marshaller must have an additional generic parameter with the `ElementUnmanagedTypeAttribute`. This parameter can optionally be constrained to `: unmanaged` (but the system will not require this). The attributed parameter will be filled in with a generics-compatible representation of the unmanaged type for the collection's element type (`nint` will be used when the native type is a pointer type).
|
A collection marshaller must have the `ContiguousCollectionMarshallerAttribute` applied to the entry-point type. A collection marshaller for a managed type will have similar generics handling as the value marshaller case; however, there is one difference. A collection marshaller must have an additional generic parameter at the end of the generic parameter list. This parameter can optionally be constrained to `: unmanaged` (but the system will not require this). The additional parameter will be filled in with a generics-compatible representation of the unmanaged type for the collection's element type (`nint` will be used when the native type is a pointer type).
|
||||||
|
|
||||||
The type `TNative` can be any `unmanaged` type. It represents whatever unmanaged type the marshaller marshals the managed type to.
|
The type `TNative` can be any `unmanaged` type. It represents whatever unmanaged type the marshaller marshals the managed type to.
|
||||||
|
|
||||||
|
@ -463,9 +443,11 @@ The type `TNative` can be any `unmanaged` type. It represents whatever unmanaged
|
||||||
### Stateless Managed->Unmanaged
|
### Stateless Managed->Unmanaged
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TCollection<,,,...>), InMarshaller = typeof(ManagedToNative))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))]
|
||||||
[UnmanagedToManagedMarshallers(typeof(TCollection<,,,...>), OutMarshaller = typeof(ManagedToNative))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.UnmanagedToManagedOut, typeof(ManagedToNative))]
|
||||||
static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ElementIn, typeof(ManagedToNative))]
|
||||||
|
[ContiguousCollectionMarshaller]
|
||||||
|
static class TMarshaller<T, U, V..., TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
public static class ManagedToNative
|
public static class ManagedToNative
|
||||||
{
|
{
|
||||||
|
@ -487,13 +469,14 @@ static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> w
|
||||||
The element type of the `Span` for the caller-allocated buffer can be any type that guarantees any alignment requirements, including `TUnmanagedElement`.
|
The element type of the `Span` for the caller-allocated buffer can be any type that guarantees any alignment requirements, including `TUnmanagedElement`.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TCollection<,,,...>), InMarshaller = typeof(ManagedToNative))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))]
|
||||||
[UnmanagedToManagedMarshallers(typeof(TCollection<,,,...>), OutMarshaller = typeof(ManagedToNative))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ElementIn, typeof(ManagedToNative))]
|
||||||
static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
[ContiguousCollectionMarshaller]
|
||||||
|
static class TMarshaller<T, U, V..., TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
[CustomTypeMarshallerFeatures(BufferSize = 0x200)]
|
|
||||||
public static class ManagedToNative
|
public static class ManagedToNative
|
||||||
{
|
{
|
||||||
|
public static int BufferSize { get; }
|
||||||
public static TNative AllocateContainerForUnmanagedElements(TCollection managed, Span<TOther> buffer, out int numElements); // Can throw exceptions
|
public static TNative AllocateContainerForUnmanagedElements(TCollection managed, Span<TOther> buffer, out int numElements); // Can throw exceptions
|
||||||
|
|
||||||
public static ReadOnlySpan<TManagedElement> GetManagedValuesSource(TCollection managed); // Can throw exceptions
|
public static ReadOnlySpan<TManagedElement> GetManagedValuesSource(TCollection managed); // Can throw exceptions
|
||||||
|
@ -511,9 +494,11 @@ static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> w
|
||||||
### Stateless Unmanaged->Managed
|
### Stateless Unmanaged->Managed
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TCollection<,,,...>), OutMarshaller = typeof(NativeToManaged))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ManagedToUnmanagedOut, typeof(NativeToManaged))]
|
||||||
[UnmanagedToManagedMarshallers(typeof(TCollection<,,,...>), InMarshaller = typeof(NativeToManaged))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.UnmanagedToManagedIn, typeof(NativeToManaged))]
|
||||||
static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ElementOut, typeof(NativeToManaged))]
|
||||||
|
[ContiguousCollectionMarshaller]
|
||||||
|
static class TMarshaller<T, U, V..., TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
public static class NativeToManaged
|
public static class NativeToManaged
|
||||||
{
|
{
|
||||||
|
@ -531,16 +516,16 @@ static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> w
|
||||||
|
|
||||||
### Stateless Unmanaged->Managed with Guaranteed Unmarshalling
|
### Stateless Unmanaged->Managed with Guaranteed Unmarshalling
|
||||||
|
|
||||||
This shape directs the generator to emit the `ConvertToManagedGuaranteed` call in the "GuaranteedUnmarshal" phase of marshalling.
|
This shape directs the generator to emit the `ConvertToManagedFinally` call in the "GuaranteedUnmarshal" phase of marshalling.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TCollection<,,,...>), OutMarshaller = typeof(NativeToManaged))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ManagedToUnmanagedOut, typeof(NativeToManaged))]
|
||||||
[UnmanagedToManagedMarshallers(typeof(TCollection<,,,...>), InMarshaller = typeof(NativeToManaged))]
|
[ContiguousCollectionMarshaller]
|
||||||
static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
static class TMarshaller<T, U, V..., TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
public static class NativeToManaged
|
public static class NativeToManaged
|
||||||
{
|
{
|
||||||
public static TCollection AllocateContainerForManagedElementsGuaranteed(TNative unmanaged, int length); // Should not throw exceptions other than OutOfMemoryException.
|
public static TCollection AllocateContainerForManagedElementsFinally(TNative unmanaged, int length); // Should not throw exceptions other than OutOfMemoryException.
|
||||||
|
|
||||||
public static Span<TManagedElement> GetManagedValuesDestination(T[] managed) => managed; // Can throw exceptions
|
public static Span<TManagedElement> GetManagedValuesDestination(T[] managed) => managed; // Can throw exceptions
|
||||||
|
|
||||||
|
@ -554,10 +539,11 @@ static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> w
|
||||||
|
|
||||||
### Stateless Bidirectional
|
### Stateless Bidirectional
|
||||||
```csharp
|
```csharp
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TCollection<,,,...>), RefMarshaller = typeof(Bidirectional))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ManagedToUnmanagedRef, typeof(Bidirectional))]
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TCollection<,,,...>), RefMarshaller = typeof(Bidirectional))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.UnmanagedToManagedRef, typeof(Bidirectional))]
|
||||||
[ElementMarshaller(typeof(TManaged<,,,...>), typeof(Bidirectional))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ElementRef, typeof(Bidirectional))]
|
||||||
static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
[ContiguousCollectionMarshaller]
|
||||||
|
static class TMarshaller<T, U, V..., TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
public static class Bidirectional
|
public static class Bidirectional
|
||||||
{
|
{
|
||||||
|
@ -572,9 +558,10 @@ static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> w
|
||||||
### Stateful Managed->Unmanaged
|
### Stateful Managed->Unmanaged
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TCollection<,,,...>), InMarshaller = typeof(ManagedToNative))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))]
|
||||||
[UnmanagedToManagedMarshallers(typeof(TCollection<,,,...>), OutMarshaller = typeof(ManagedToNative))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.UnmanagedToManagedOut, typeof(ManagedToNative))]
|
||||||
static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
[ContiguousCollectionMarshaller]
|
||||||
|
static class TMarshaller<T, U, V..., TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
public struct ManagedToNative // Can be ref struct
|
public struct ManagedToNative // Can be ref struct
|
||||||
{
|
{
|
||||||
|
@ -592,7 +579,7 @@ static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> w
|
||||||
|
|
||||||
public static ref TOther GetPinnableReference(TCollection collection); // Optional. Can throw exceptions. Result pinnned and passed to Invoke.
|
public static ref TOther GetPinnableReference(TCollection collection); // Optional. Can throw exceptions. Result pinnned and passed to Invoke.
|
||||||
|
|
||||||
public void NotifyInvokeSucceeded(); // Optional. Should not throw exceptions.
|
public void OnInvoked(); // Optional. Should not throw exceptions.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,13 +589,14 @@ static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> w
|
||||||
The element type of the `Span` for the caller-allocated buffer can be any type that guarantees any alignment requirements.
|
The element type of the `Span` for the caller-allocated buffer can be any type that guarantees any alignment requirements.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TCollection<,,,...>), InMarshaller = typeof(ManagedToNative))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))]
|
||||||
[UnmanagedToManagedMarshallers(typeof(TCollection<,,,...>), OutMarshaller = typeof(ManagedToNative))]
|
[ContiguousCollectionMarshaller]
|
||||||
static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
static class TMarshaller<T, U, V..., TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
[CustomTypeMarshallerFeatures(BufferSize = 0x200)]
|
|
||||||
public struct ManagedToNative // Can be ref struct
|
public struct ManagedToNative // Can be ref struct
|
||||||
{
|
{
|
||||||
|
public static int BufferSize { get; }
|
||||||
|
|
||||||
public ManagedToNative(); // Optional, can throw exceptions.
|
public ManagedToNative(); // Optional, can throw exceptions.
|
||||||
|
|
||||||
public void FromManaged(TCollection collection, Span<TBuffer> buffer); // Can throw exceptions.
|
public void FromManaged(TCollection collection, Span<TBuffer> buffer); // Can throw exceptions.
|
||||||
|
@ -623,7 +611,7 @@ static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> w
|
||||||
|
|
||||||
public static ref TOther GetPinnableReference(TCollection collection); // Optional. Can throw exceptions. Result pinnned and passed to Invoke.
|
public static ref TOther GetPinnableReference(TCollection collection); // Optional. Can throw exceptions. Result pinnned and passed to Invoke.
|
||||||
|
|
||||||
public void NotifyInvokeSucceeded(); // Optional. Should not throw exceptions.
|
public void OnInvoked(); // Optional. Should not throw exceptions.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,9 +620,10 @@ static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> w
|
||||||
### Stateful Unmanaged->Managed
|
### Stateful Unmanaged->Managed
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TCollection<,,,...>), OutMarshaller = typeof(NativeToManaged))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ManagedToUnmanagedOut, typeof(NativeToManaged))]
|
||||||
[UnmanagedToManagedMarshallers(typeof(TCollection<,,,...>), InMarshaller = typeof(NativeToManaged))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.UnmanagedToManagedIn, typeof(NativeToManaged))]
|
||||||
static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
[ContiguousCollectionMarshaller]
|
||||||
|
static class TMarshaller<T, U, V..., TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
public struct NativeToManaged // Can be ref struct
|
public struct NativeToManaged // Can be ref struct
|
||||||
{
|
{
|
||||||
|
@ -657,9 +646,9 @@ static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> w
|
||||||
### Stateful Unmanaged->Managed with Guaranteed Unmarshalling
|
### Stateful Unmanaged->Managed with Guaranteed Unmarshalling
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TCollection<,,,...>), OutMarshaller = typeof(NativeToManaged))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ManagedToUnmanagedOut, typeof(NativeToManaged))]
|
||||||
[UnmanagedToManagedMarshallers(typeof(TCollection<,,,...>), InMarshaller = typeof(NativeToManaged))]
|
[ContiguousCollectionMarshaller]
|
||||||
static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
static class TMarshaller<T, U, V..., TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
public struct NativeToManaged // Can be ref struct
|
public struct NativeToManaged // Can be ref struct
|
||||||
{
|
{
|
||||||
|
@ -671,7 +660,7 @@ static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> w
|
||||||
|
|
||||||
public Span<TManagedElement> GetManagedValuesDestination(int length); // Can throw exceptions.
|
public Span<TManagedElement> GetManagedValuesDestination(int length); // Can throw exceptions.
|
||||||
|
|
||||||
public TCollection ToManagedGuaranteed(); // Can throw exceptions
|
public TCollection ToManagedFinally(); // Can throw exceptions
|
||||||
|
|
||||||
public void Free(); // Optional. Should not throw exceptions.
|
public void Free(); // Optional. Should not throw exceptions.
|
||||||
}
|
}
|
||||||
|
@ -681,9 +670,10 @@ static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> w
|
||||||
|
|
||||||
### Stateful Bidirectional
|
### Stateful Bidirectional
|
||||||
```csharp
|
```csharp
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TCollection<,,,...>), RefMarshaller = typeof(Bidirectional))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.ManagedToUnmanagedRef, typeof(Bidirectional))]
|
||||||
[ManagedToUnmanagedMarshallers(typeof(TCollection<,,,...>), RefMarshaller = typeof(Bidirectional))]
|
[CustomMarshaller(typeof(TCollection<,,,...>), MarshalMode.UnmanagedToManagedRef, typeof(Bidirectional))]
|
||||||
static class TMarshaller<T, U, V..., [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
[ContiguousCollectionMarshaller]
|
||||||
|
static class TMarshaller<T, U, V..., TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
public struct Bidirectional // Can be ref struct
|
public struct Bidirectional // Can be ref struct
|
||||||
{
|
{
|
||||||
|
@ -702,7 +692,7 @@ There's a few optional members in the above shapes. This section explains what t
|
||||||
|
|
||||||
The `Free` method on each shape supports releasing any unmanaged (or managed in the stateful shapes) resources. This method is optional as the `Free` method is required to be called in a `finally` clause and emitting a `try-finally` block with only method calls to empty methods puts a lot of stress on the JIT to inline all of the methods and realize that they are no-ops to remove the `finally` clause. Additionally, just having the `try-finally` block wrapping the main code can cause some de-optimizations.
|
The `Free` method on each shape supports releasing any unmanaged (or managed in the stateful shapes) resources. This method is optional as the `Free` method is required to be called in a `finally` clause and emitting a `try-finally` block with only method calls to empty methods puts a lot of stress on the JIT to inline all of the methods and realize that they are no-ops to remove the `finally` clause. Additionally, just having the `try-finally` block wrapping the main code can cause some de-optimizations.
|
||||||
|
|
||||||
### NotifyInvokeSucceeded method
|
### OnInvoked method
|
||||||
|
|
||||||
This method is called after a stub successfully invokes the target code (unmanaged code in a P/Invoke scenario, managed code in a Reverse P/Invoke scenario). As this method would be called in a very large majority of cases in P/Invoke-style scenarios and has only limited utility (its main use is to provide a good place to call `GC.KeepAlive` that does not require a `try-finally` block), we decided to make it optional.
|
This method is called after a stub successfully invokes the target code (unmanaged code in a P/Invoke scenario, managed code in a Reverse P/Invoke scenario). As this method would be called in a very large majority of cases in P/Invoke-style scenarios and has only limited utility (its main use is to provide a good place to call `GC.KeepAlive` that does not require a `try-finally` block), we decided to make it optional.
|
||||||
|
|
||||||
|
@ -731,7 +721,7 @@ The marshaller type must be an entry-point marshaller type as defined above and
|
||||||
- The type must either be:
|
- The type must either be:
|
||||||
- Non-generic
|
- Non-generic
|
||||||
- A closed generic
|
- A closed generic
|
||||||
- An open generic with as many generic parameters with compatible constraints as the managed type (excluding up to one generic parameter with the `ElementUnmanagedTypeAttribute`)
|
- An open generic with as many generic parameters with compatible constraints as the managed type (excluding one generic parameter if the marshaller has the `ContiguousCollectionMarshallerAttribute` attribute)
|
||||||
- If used in `NativeMarshallingAttribute`, the type should be at least as visible as the managed type.
|
- If used in `NativeMarshallingAttribute`, the type should be at least as visible as the managed type.
|
||||||
|
|
||||||
Passing size info for parameters will be based to the [V1 design](SpanMarshallers.md#providing-additional-data-for-collection-marshalling) and the properties/fields on `MarshalUsingAttribute` will remain unchanged.
|
Passing size info for parameters will be based to the [V1 design](SpanMarshallers.md#providing-additional-data-for-collection-marshalling) and the properties/fields on `MarshalUsingAttribute` will remain unchanged.
|
||||||
|
|
|
@ -69,8 +69,6 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(NetCoreAppCurrentTargetFrameworkMoniker)' == '$(TargetFrameworkMoniker)' and '$(IncludeLibraryImportGeneratorSources)' != 'false'">
|
<ItemGroup Condition="'$(NetCoreAppCurrentTargetFrameworkMoniker)' == '$(TargetFrameworkMoniker)' and '$(IncludeLibraryImportGeneratorSources)' != 'false'">
|
||||||
<Compile Include="$(LibrariesProjectRoot)System.Runtime.InteropServices/tests/Ancillary.Interop/CustomMarshallerAttribute.cs" />
|
|
||||||
<Compile Include="$(LibrariesProjectRoot)System.Runtime.InteropServices/tests/Ancillary.Interop/Scenario.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace System.DirectoryServices.Protocols
|
||||||
public int packageListLength;
|
public int packageListLength;
|
||||||
|
|
||||||
#if NET7_0_OR_GREATER
|
#if NET7_0_OR_GREATER
|
||||||
[CustomMarshaller(typeof(SEC_WINNT_AUTH_IDENTITY_EX), Scenario.ManagedToUnmanagedIn, typeof(Marshaller))]
|
[CustomMarshaller(typeof(SEC_WINNT_AUTH_IDENTITY_EX), MarshalMode.ManagedToUnmanagedIn, typeof(Marshaller))]
|
||||||
internal static class Marshaller
|
internal static class Marshaller
|
||||||
{
|
{
|
||||||
public static Native ConvertToUnmanaged(SEC_WINNT_AUTH_IDENTITY_EX managed)
|
public static Native ConvertToUnmanaged(SEC_WINNT_AUTH_IDENTITY_EX managed)
|
||||||
|
|
|
@ -40,7 +40,7 @@ internal static partial class Interop
|
||||||
internal uint nStartPage;
|
internal uint nStartPage;
|
||||||
|
|
||||||
#if NET7_0_OR_GREATER
|
#if NET7_0_OR_GREATER
|
||||||
[CustomMarshaller(typeof(CRYPTUI_VIEWCERTIFICATE_STRUCTW), Scenario.Default, typeof(Marshaller))]
|
[CustomMarshaller(typeof(CRYPTUI_VIEWCERTIFICATE_STRUCTW), MarshalMode.Default, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public static Native ConvertToUnmanaged(CRYPTUI_VIEWCERTIFICATE_STRUCTW managed) => new(managed);
|
public static Native ConvertToUnmanaged(CRYPTUI_VIEWCERTIFICATE_STRUCTW managed) => new(managed);
|
||||||
|
@ -152,7 +152,7 @@ internal static partial class Interop
|
||||||
internal IntPtr hSelectedCertStore;
|
internal IntPtr hSelectedCertStore;
|
||||||
|
|
||||||
#if NET7_0_OR_GREATER
|
#if NET7_0_OR_GREATER
|
||||||
[CustomMarshaller(typeof(CRYPTUI_SELECTCERTIFICATE_STRUCTW), Scenario.Default, typeof(Marshaller))]
|
[CustomMarshaller(typeof(CRYPTUI_SELECTCERTIFICATE_STRUCTW), MarshalMode.Default, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public static Native ConvertToUnmanaged(CRYPTUI_SELECTCERTIFICATE_STRUCTW managed) => new(managed);
|
public static Native ConvertToUnmanaged(CRYPTUI_SELECTCERTIFICATE_STRUCTW managed) => new(managed);
|
||||||
|
|
|
@ -56,7 +56,7 @@ internal static partial class Interop
|
||||||
uint modifiers);
|
uint modifiers);
|
||||||
|
|
||||||
#if NET7_0_OR_GREATER
|
#if NET7_0_OR_GREATER
|
||||||
[CustomMarshaller(typeof(StringBuilder), Scenario.ManagedToUnmanagedIn, typeof(SimpleStringBufferMarshaller))]
|
[CustomMarshaller(typeof(StringBuilder), MarshalMode.ManagedToUnmanagedIn, typeof(SimpleStringBufferMarshaller))]
|
||||||
private static unsafe class SimpleStringBufferMarshaller
|
private static unsafe class SimpleStringBufferMarshaller
|
||||||
{
|
{
|
||||||
public static void* ConvertToUnmanaged(StringBuilder builder)
|
public static void* ConvertToUnmanaged(StringBuilder builder)
|
||||||
|
|
|
@ -262,7 +262,7 @@ internal static partial class Interop
|
||||||
[MarshalAs(UnmanagedType.Bool)]
|
[MarshalAs(UnmanagedType.Bool)]
|
||||||
public bool AutoLoginIfChallenged;
|
public bool AutoLoginIfChallenged;
|
||||||
#if NET7_0_OR_GREATER
|
#if NET7_0_OR_GREATER
|
||||||
[CustomMarshaller(typeof(WINHTTP_AUTOPROXY_OPTIONS), Scenario.Default, typeof(Marshaller))]
|
[CustomMarshaller(typeof(WINHTTP_AUTOPROXY_OPTIONS), MarshalMode.Default, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public static Native ConvertToUnmanaged(WINHTTP_AUTOPROXY_OPTIONS managed) => new(managed);
|
public static Native ConvertToUnmanaged(WINHTTP_AUTOPROXY_OPTIONS managed) => new(managed);
|
||||||
|
|
|
@ -28,7 +28,7 @@ internal static partial class Interop
|
||||||
private ushort wReserved1;
|
private ushort wReserved1;
|
||||||
private ushort dwSupport;
|
private ushort dwSupport;
|
||||||
#if NET7_0_OR_GREATER
|
#if NET7_0_OR_GREATER
|
||||||
[CustomMarshaller(typeof(WAVEOUTCAPS), Scenario.Default, typeof(Marshaller))]
|
[CustomMarshaller(typeof(WAVEOUTCAPS), MarshalMode.Default, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public static Native ConvertToUnmanaged(WAVEOUTCAPS managed) => new(managed);
|
public static Native ConvertToUnmanaged(WAVEOUTCAPS managed) => new(managed);
|
||||||
|
|
|
@ -75,7 +75,7 @@ internal static partial class Interop
|
||||||
internal byte[] MulticastAddress; // IP address of group.
|
internal byte[] MulticastAddress; // IP address of group.
|
||||||
internal int InterfaceIndex; // Local interface index.
|
internal int InterfaceIndex; // Local interface index.
|
||||||
|
|
||||||
[CustomMarshaller(typeof(IPv6MulticastRequest), Scenario.Default, typeof(Marshaller))]
|
[CustomMarshaller(typeof(IPv6MulticastRequest), MarshalMode.Default, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public static Native ConvertToUnmanaged(IPv6MulticastRequest managed) => new(managed);
|
public static Native ConvertToUnmanaged(IPv6MulticastRequest managed) => new(managed);
|
||||||
|
|
|
@ -703,7 +703,7 @@ namespace Microsoft.Win32
|
||||||
public uint Type;
|
public uint Type;
|
||||||
|
|
||||||
#if NET7_0_OR_GREATER
|
#if NET7_0_OR_GREATER
|
||||||
[CustomMarshaller(typeof(EvtStringVariant), Scenario.Default, typeof(Marshaller))]
|
[CustomMarshaller(typeof(EvtStringVariant), MarshalMode.Default, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public static Native ConvertToUnmanaged(EvtStringVariant managed) => new(managed);
|
public static Native ConvertToUnmanaged(EvtStringVariant managed) => new(managed);
|
||||||
|
|
|
@ -188,7 +188,7 @@ internal static partial class Interop
|
||||||
internal int fwType;
|
internal int fwType;
|
||||||
|
|
||||||
#if NET7_0_OR_GREATER
|
#if NET7_0_OR_GREATER
|
||||||
[CustomMarshaller(typeof(DOCINFO), Scenario.ManagedToUnmanagedIn, typeof(Marshaller))]
|
[CustomMarshaller(typeof(DOCINFO), MarshalMode.ManagedToUnmanagedIn, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public static Native ConvertToUnmanaged(DOCINFO managed) => new(managed);
|
public static Native ConvertToUnmanaged(DOCINFO managed) => new(managed);
|
||||||
|
|
|
@ -872,10 +872,12 @@
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\AnsiStringMarshaller.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\AnsiStringMarshaller.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\ArrayMarshaller.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\ArrayMarshaller.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\BStrStringMarshaller.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\BStrStringMarshaller.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\CustomMarshallerAttribute.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\CustomTypeMarshallerAttribute.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\CustomTypeMarshallerAttribute.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\CustomTypeMarshallerDirection.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\CustomTypeMarshallerDirection.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\CustomTypeMarshallerFeatures.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\CustomTypeMarshallerFeatures.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\CustomTypeMarshallerKind.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\CustomTypeMarshallerKind.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\MarshalMode.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\MarshalUsingAttribute.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\MarshalUsingAttribute.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\NativeMarshallingAttribute.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\NativeMarshallingAttribute.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\PointerArrayMarshaller.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshalling\PointerArrayMarshaller.cs" />
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
namespace System.Runtime.InteropServices.Marshalling
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute to indicate an entry point type for defining a marshaller.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true)]
|
||||||
|
public sealed class CustomMarshallerAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Create a <see cref="CustomMarshallerAttribute"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="managedType">Managed type to marshal.</param>
|
||||||
|
/// <param name="marshalMode">The marshalling mode this attribute applies to.</param>
|
||||||
|
/// <param name="marshallerType">Type used for marshalling.</param>
|
||||||
|
public CustomMarshallerAttribute(Type managedType, MarshalMode marshalMode, Type marshallerType)
|
||||||
|
{
|
||||||
|
ManagedType = managedType;
|
||||||
|
MarshalMode = marshalMode;
|
||||||
|
MarshallerType = marshallerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The managed type to marshal.
|
||||||
|
/// </summary>
|
||||||
|
public Type ManagedType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The marshalling mode this attribute applies to.
|
||||||
|
/// </summary>
|
||||||
|
public MarshalMode MarshalMode { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Type used for marshalling.
|
||||||
|
/// </summary>
|
||||||
|
public Type MarshallerType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Placeholder type for generic parameter
|
||||||
|
/// </summary>
|
||||||
|
public struct GenericPlaceholder
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,22 +4,17 @@
|
||||||
#if MICROSOFT_INTEROP_SOURCEGENERATION
|
#if MICROSOFT_INTEROP_SOURCEGENERATION
|
||||||
namespace Microsoft.Interop
|
namespace Microsoft.Interop
|
||||||
#else
|
#else
|
||||||
namespace System.Runtime.InteropServices
|
namespace System.Runtime.InteropServices.Marshalling
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An enumeration representing the different marshalling scenarios in our marshalling model.
|
/// An enumeration representing the different marshalling modes in our marshalling model.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
#if LIBRARYIMPORT_GENERATOR_TEST || MICROSOFT_INTEROP_SOURCEGENERATION
|
public enum MarshalMode
|
||||||
public
|
|
||||||
#else
|
|
||||||
internal
|
|
||||||
#endif
|
|
||||||
enum Scenario
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All scenarios. A marshaller specified with this scenario will be used if there is not a specific
|
/// All modes. A marshaller specified with this mode will be used if there is not a specific
|
||||||
/// marshaller specified for a given usage scenario.
|
/// marshaller specified for a given usage mode.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Default,
|
Default,
|
||||||
/// <summary>
|
/// <summary>
|
|
@ -500,6 +500,13 @@ namespace Microsoft.Interop.Analyzers
|
||||||
|
|
||||||
if (!hasCustomTypeMarshallerAttribute)
|
if (!hasCustomTypeMarshallerAttribute)
|
||||||
{
|
{
|
||||||
|
if (ManualTypeMarshallingHelper.HasEntryPointMarshallerAttribute(entryType))
|
||||||
|
{
|
||||||
|
// TEMPORARY: Don't analyze V2 analyzers in this method for now.
|
||||||
|
// We'll add support soon, but for now just don't emit warnings to use the V1 marshaller design
|
||||||
|
// when using the V2 design.
|
||||||
|
return;
|
||||||
|
}
|
||||||
context.ReportDiagnostic(
|
context.ReportDiagnostic(
|
||||||
attributeData.CreateDiagnostic(
|
attributeData.CreateDiagnostic(
|
||||||
NativeTypeMustHaveCustomTypeMarshallerAttributeRule,
|
NativeTypeMustHaveCustomTypeMarshallerAttributeRule,
|
||||||
|
|
|
@ -358,13 +358,13 @@ namespace Microsoft.Interop
|
||||||
// Since the char type in an array will not be part of the P/Invoke signature, we can
|
// Since the char type in an array will not be part of the P/Invoke signature, we can
|
||||||
// use the regular blittable marshaller in all cases.
|
// use the regular blittable marshaller in all cases.
|
||||||
new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: true),
|
new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: true),
|
||||||
new AttributedMarshallingModelOptions(runtimeMarshallingDisabled, Scenario.ElementIn, Scenario.ElementRef, Scenario.ElementOut));
|
new AttributedMarshallingModelOptions(runtimeMarshallingDisabled, MarshalMode.ElementIn, MarshalMode.ElementRef, MarshalMode.ElementOut));
|
||||||
// We don't need to include the later generator factories for collection elements
|
// We don't need to include the later generator factories for collection elements
|
||||||
// as the later generator factories only apply to parameters.
|
// as the later generator factories only apply to parameters.
|
||||||
generatorFactory = new AttributedMarshallingModelGeneratorFactory(
|
generatorFactory = new AttributedMarshallingModelGeneratorFactory(
|
||||||
generatorFactory,
|
generatorFactory,
|
||||||
elementFactory,
|
elementFactory,
|
||||||
new AttributedMarshallingModelOptions(runtimeMarshallingDisabled, Scenario.ManagedToUnmanagedIn, Scenario.ManagedToUnmanagedRef, Scenario.ManagedToUnmanagedOut));
|
new AttributedMarshallingModelOptions(runtimeMarshallingDisabled, MarshalMode.ManagedToUnmanagedIn, MarshalMode.ManagedToUnmanagedRef, MarshalMode.ManagedToUnmanagedOut));
|
||||||
|
|
||||||
generatorFactory = new ByValueContentsMarshalKindValidator(generatorFactory);
|
generatorFactory = new ByValueContentsMarshalKindValidator(generatorFactory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,32 +24,32 @@ namespace Microsoft.Interop
|
||||||
MarshallingInfo? CollectionElementMarshallingInfo);
|
MarshallingInfo? CollectionElementMarshallingInfo);
|
||||||
|
|
||||||
public readonly record struct CustomTypeMarshallers(
|
public readonly record struct CustomTypeMarshallers(
|
||||||
ImmutableDictionary<Scenario, CustomTypeMarshallerData> Scenarios)
|
ImmutableDictionary<MarshalMode, CustomTypeMarshallerData> Modes)
|
||||||
{
|
{
|
||||||
public CustomTypeMarshallerData GetScenarioOrDefault(Scenario scenario)
|
public CustomTypeMarshallerData GetModeOrDefault(MarshalMode mode)
|
||||||
{
|
{
|
||||||
CustomTypeMarshallerData data;
|
CustomTypeMarshallerData data;
|
||||||
if (Scenarios.TryGetValue(scenario, out data))
|
if (Modes.TryGetValue(mode, out data))
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
if (Scenarios.TryGetValue(Scenario.Default, out data))
|
if (Modes.TryGetValue(MarshalMode.Default, out data))
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
// TODO: Hard failure based on previous implementation
|
// TODO: Hard failure based on previous implementation
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetScenarioOrDefault(Scenario scenario, out CustomTypeMarshallerData data)
|
public bool TryGetModeOrDefault(MarshalMode mode, out CustomTypeMarshallerData data)
|
||||||
{
|
{
|
||||||
if (Scenarios.TryGetValue(scenario, out data))
|
if (Modes.TryGetValue(mode, out data))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return Scenarios.TryGetValue(Scenario.Default, out data);
|
return Modes.TryGetValue(MarshalMode.Default, out data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDefinedOrDefault(Scenario scenario)
|
public bool IsDefinedOrDefault(MarshalMode mode)
|
||||||
{
|
{
|
||||||
return Scenarios.ContainsKey(scenario) || Scenarios.ContainsKey(Scenario.Default);
|
return Modes.ContainsKey(mode) || Modes.ContainsKey(MarshalMode.Default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ namespace Microsoft.Interop
|
||||||
public static bool IsLinearCollectionEntryPoint(INamedTypeSymbol entryPointType)
|
public static bool IsLinearCollectionEntryPoint(INamedTypeSymbol entryPointType)
|
||||||
{
|
{
|
||||||
return entryPointType.IsGenericType
|
return entryPointType.IsGenericType
|
||||||
&& entryPointType.TypeParameters.Last().GetAttributes().Any(attr => attr.AttributeClass.ToDisplayString() == TypeNames.ElementUnmanagedTypeAttribute);
|
&& entryPointType.GetAttributes().Any(attr => attr.AttributeClass.ToDisplayString() == TypeNames.ContiguousCollectionMarshallerAttribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool HasEntryPointMarshallerAttribute(ITypeSymbol entryPointType)
|
public static bool HasEntryPointMarshallerAttribute(ITypeSymbol entryPointType)
|
||||||
|
@ -116,7 +116,7 @@ namespace Microsoft.Interop
|
||||||
// We expect a callback for getting the element marshalling info when handling linear collection marshalling
|
// We expect a callback for getting the element marshalling info when handling linear collection marshalling
|
||||||
Debug.Assert(!isLinearCollectionMarshalling || getMarshallingInfoForElement is not null);
|
Debug.Assert(!isLinearCollectionMarshalling || getMarshallingInfoForElement is not null);
|
||||||
|
|
||||||
Dictionary<Scenario, CustomTypeMarshallerData> scenarios = new();
|
Dictionary<MarshalMode, CustomTypeMarshallerData> modes = new();
|
||||||
foreach (AttributeData attr in attrs)
|
foreach (AttributeData attr in attrs)
|
||||||
{
|
{
|
||||||
Debug.Assert(attr.ConstructorArguments.Length == 3);
|
Debug.Assert(attr.ConstructorArguments.Length == 3);
|
||||||
|
@ -136,7 +136,7 @@ namespace Microsoft.Interop
|
||||||
&& !compilation.HasImplicitConversion(managedType, managedTypeInst))
|
&& !compilation.HasImplicitConversion(managedType, managedTypeInst))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var marshallerScenario = (Scenario)attr.ConstructorArguments[1].Value!;
|
var marshalMode = (MarshalMode)attr.ConstructorArguments[1].Value!;
|
||||||
|
|
||||||
ITypeSymbol? marshallerTypeOnAttr = attr.ConstructorArguments[2].Value as ITypeSymbol;
|
ITypeSymbol? marshallerTypeOnAttr = attr.ConstructorArguments[2].Value as ITypeSymbol;
|
||||||
if (marshallerTypeOnAttr is null)
|
if (marshallerTypeOnAttr is null)
|
||||||
|
@ -168,51 +168,51 @@ namespace Microsoft.Interop
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: We can probably get rid of MarshallingDirection and just use Scenario instead
|
// TODO: We can probably get rid of MarshallingDirection and just use Scenario instead
|
||||||
MarshallingDirection direction = marshallerScenario switch
|
MarshallingDirection direction = marshalMode switch
|
||||||
{
|
{
|
||||||
Scenario.Default
|
MarshalMode.Default
|
||||||
=> MarshallingDirection.Bidirectional,
|
=> MarshallingDirection.Bidirectional,
|
||||||
|
|
||||||
Scenario.ManagedToUnmanagedIn
|
MarshalMode.ManagedToUnmanagedIn
|
||||||
or Scenario.UnmanagedToManagedOut
|
or MarshalMode.UnmanagedToManagedOut
|
||||||
=> MarshallingDirection.ManagedToUnmanaged,
|
=> MarshallingDirection.ManagedToUnmanaged,
|
||||||
|
|
||||||
Scenario.ManagedToUnmanagedOut
|
MarshalMode.ManagedToUnmanagedOut
|
||||||
or Scenario.UnmanagedToManagedIn
|
or MarshalMode.UnmanagedToManagedIn
|
||||||
=> MarshallingDirection.UnmanagedToManaged,
|
=> MarshallingDirection.UnmanagedToManaged,
|
||||||
|
|
||||||
Scenario.ManagedToUnmanagedRef
|
MarshalMode.ManagedToUnmanagedRef
|
||||||
or Scenario.UnmanagedToManagedRef
|
or MarshalMode.UnmanagedToManagedRef
|
||||||
=> MarshallingDirection.Bidirectional,
|
=> MarshallingDirection.Bidirectional,
|
||||||
|
|
||||||
Scenario.ElementIn
|
MarshalMode.ElementIn
|
||||||
or Scenario.ElementRef
|
or MarshalMode.ElementRef
|
||||||
or Scenario.ElementOut
|
or MarshalMode.ElementOut
|
||||||
=> MarshallingDirection.Bidirectional,
|
=> MarshallingDirection.Bidirectional,
|
||||||
|
|
||||||
_ => throw new UnreachableException()
|
_ => throw new UnreachableException()
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Report invalid shape for scenario
|
// TODO: Report invalid shape for mode
|
||||||
// Skip checking for bidirectional support for Default scenario - always take / store marshaller data
|
// Skip checking for bidirectional support for Default mode - always take / store marshaller data
|
||||||
CustomTypeMarshallerData? data = GetMarshallerDataForType(marshallerType, direction, managedType, isLinearCollectionMarshalling, compilation, getMarshallingInfoForElement);
|
CustomTypeMarshallerData? data = GetMarshallerDataForType(marshallerType, direction, managedType, isLinearCollectionMarshalling, compilation, getMarshallingInfoForElement);
|
||||||
|
|
||||||
// TODO: Should we fire a diagnostic for duplicated scenarios or just take the last one?
|
// TODO: Should we fire a diagnostic for duplicated modes or just take the last one?
|
||||||
if (data is null
|
if (data is null
|
||||||
|| scenarios.ContainsKey(marshallerScenario))
|
|| modes.ContainsKey(marshalMode))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
scenarios.Add(marshallerScenario, data.Value);
|
modes.Add(marshalMode, data.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scenarios.Count == 0)
|
if (modes.Count == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
marshallers = new CustomTypeMarshallers()
|
marshallers = new CustomTypeMarshallers()
|
||||||
{
|
{
|
||||||
Scenarios = scenarios.ToImmutableDictionary()
|
Modes = modes.ToImmutableDictionary()
|
||||||
};
|
};
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -392,10 +392,10 @@ namespace Microsoft.Interop
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Native type is the first parameter of ConvertToManaged or ConvertToManagedGuaranteed
|
// Native type is the first parameter of ConvertToManaged or ConvertToManagedFinally
|
||||||
if (methods.ToManagedGuaranteed is not null)
|
if (methods.ToManagedFinally is not null)
|
||||||
{
|
{
|
||||||
nativeType = methods.ToManagedGuaranteed.Parameters[0].Type;
|
nativeType = methods.ToManagedFinally.Parameters[0].Type;
|
||||||
}
|
}
|
||||||
else if (methods.ToManaged is not null)
|
else if (methods.ToManaged is not null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace Microsoft.Interop
|
||||||
ToManaged = 0x10,
|
ToManaged = 0x10,
|
||||||
GuaranteedUnmarshal = 0x20,
|
GuaranteedUnmarshal = 0x20,
|
||||||
Free = 0x40,
|
Free = 0x40,
|
||||||
NotifyInvokeSucceeded = 0x80,
|
OnInvoked = 0x80,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ShapeMemberNames
|
public static class ShapeMemberNames
|
||||||
|
@ -36,7 +36,7 @@ namespace Microsoft.Interop
|
||||||
public static class Stateless
|
public static class Stateless
|
||||||
{
|
{
|
||||||
public const string ConvertToManaged = nameof(ConvertToManaged);
|
public const string ConvertToManaged = nameof(ConvertToManaged);
|
||||||
public const string ConvertToManagedGuaranteed = nameof(ConvertToManagedGuaranteed);
|
public const string ConvertToManagedFinally = nameof(ConvertToManagedFinally);
|
||||||
public const string ConvertToUnmanaged = nameof(ConvertToUnmanaged);
|
public const string ConvertToUnmanaged = nameof(ConvertToUnmanaged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,11 +47,11 @@ namespace Microsoft.Interop
|
||||||
public const string ToUnmanaged = nameof(ToUnmanaged);
|
public const string ToUnmanaged = nameof(ToUnmanaged);
|
||||||
// Unmanaged to managed
|
// Unmanaged to managed
|
||||||
public const string ToManaged = nameof(ToManaged);
|
public const string ToManaged = nameof(ToManaged);
|
||||||
public const string ToManagedGuaranteed = nameof(ToManagedGuaranteed);
|
public const string ToManagedFinally = nameof(ToManagedFinally);
|
||||||
public const string FromUnmanaged = nameof(FromUnmanaged);
|
public const string FromUnmanaged = nameof(FromUnmanaged);
|
||||||
// Optional features
|
// Optional features
|
||||||
public const string Free = nameof(Free);
|
public const string Free = nameof(Free);
|
||||||
public const string NotifyInvokeSucceeded = nameof(NotifyInvokeSucceeded);
|
public const string OnInvoked = nameof(OnInvoked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ namespace Microsoft.Interop
|
||||||
|
|
||||||
// Unmanaged to managed
|
// Unmanaged to managed
|
||||||
public const string AllocateContainerForManagedElements = nameof(AllocateContainerForManagedElements);
|
public const string AllocateContainerForManagedElements = nameof(AllocateContainerForManagedElements);
|
||||||
public const string AllocateContainerForManagedElementsGuaranteed = nameof(AllocateContainerForManagedElementsGuaranteed);
|
public const string AllocateContainerForManagedElementsFinally = nameof(AllocateContainerForManagedElementsFinally);
|
||||||
public const string GetManagedValuesDestination = nameof(GetManagedValuesDestination);
|
public const string GetManagedValuesDestination = nameof(GetManagedValuesDestination);
|
||||||
public const string GetUnmanagedValuesSource = nameof(GetUnmanagedValuesSource);
|
public const string GetUnmanagedValuesSource = nameof(GetUnmanagedValuesSource);
|
||||||
}
|
}
|
||||||
|
@ -82,11 +82,11 @@ namespace Microsoft.Interop
|
||||||
public const string GetManagedValuesDestination = nameof(GetManagedValuesDestination);
|
public const string GetManagedValuesDestination = nameof(GetManagedValuesDestination);
|
||||||
public const string GetUnmanagedValuesSource = nameof(GetUnmanagedValuesSource);
|
public const string GetUnmanagedValuesSource = nameof(GetUnmanagedValuesSource);
|
||||||
public const string ToManaged = nameof(ToManaged);
|
public const string ToManaged = nameof(ToManaged);
|
||||||
public const string ToManagedGuaranteed = nameof(ToManagedGuaranteed);
|
public const string ToManagedFinally = nameof(ToManagedFinally);
|
||||||
public const string FromUnmanaged = nameof(FromUnmanaged);
|
public const string FromUnmanaged = nameof(FromUnmanaged);
|
||||||
// Optional features
|
// Optional features
|
||||||
public const string Free = nameof(Free);
|
public const string Free = nameof(Free);
|
||||||
public const string NotifyInvokeSucceeded = nameof(NotifyInvokeSucceeded);
|
public const string OnInvoked = nameof(OnInvoked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ namespace Microsoft.Interop
|
||||||
public IMethodSymbol? ToUnmanaged;
|
public IMethodSymbol? ToUnmanaged;
|
||||||
public IMethodSymbol? ToUnmanagedWithBuffer;
|
public IMethodSymbol? ToUnmanagedWithBuffer;
|
||||||
public IMethodSymbol? ToManaged;
|
public IMethodSymbol? ToManaged;
|
||||||
public IMethodSymbol? ToManagedGuaranteed;
|
public IMethodSymbol? ToManagedFinally;
|
||||||
|
|
||||||
// Linear collection
|
// Linear collection
|
||||||
public IMethodSymbol? ManagedValuesSource;
|
public IMethodSymbol? ManagedValuesSource;
|
||||||
|
@ -142,7 +142,7 @@ namespace Microsoft.Interop
|
||||||
|
|
||||||
// Unmanaged -> Managed
|
// Unmanaged -> Managed
|
||||||
IMethodSymbol? allocateManaged = LinearCollection.AllocateContainerForManagedElements(marshallerType, managedType);
|
IMethodSymbol? allocateManaged = LinearCollection.AllocateContainerForManagedElements(marshallerType, managedType);
|
||||||
IMethodSymbol? allocateManagedGuaranteed = LinearCollection.AllocateContainerForManagedElementsGuaranteed(marshallerType, managedType, spanOfT);
|
IMethodSymbol? allocateManagedGuaranteed = LinearCollection.AllocateContainerForManagedElementsFinally(marshallerType, managedType, spanOfT);
|
||||||
IMethodSymbol? managedDestination = LinearCollection.GetManagedValuesDestination(marshallerType, managedType, spanOfT);
|
IMethodSymbol? managedDestination = LinearCollection.GetManagedValuesDestination(marshallerType, managedType, spanOfT);
|
||||||
IMethodSymbol? unmanagedSource = LinearCollection.GetUnmanagedValuesSource(marshallerType, readOnlySpanOfT);
|
IMethodSymbol? unmanagedSource = LinearCollection.GetUnmanagedValuesSource(marshallerType, readOnlySpanOfT);
|
||||||
if ((allocateManaged is not null || allocateManagedGuaranteed is not null)
|
if ((allocateManaged is not null || allocateManagedGuaranteed is not null)
|
||||||
|
@ -158,7 +158,7 @@ namespace Microsoft.Interop
|
||||||
methods = methods with
|
methods = methods with
|
||||||
{
|
{
|
||||||
ToManaged = allocateManaged,
|
ToManaged = allocateManaged,
|
||||||
ToManagedGuaranteed = allocateManagedGuaranteed,
|
ToManagedFinally = allocateManagedGuaranteed,
|
||||||
ManagedValuesDestination = managedDestination,
|
ManagedValuesDestination = managedDestination,
|
||||||
UnmanagedValuesSource = unmanagedSource
|
UnmanagedValuesSource = unmanagedSource
|
||||||
};
|
};
|
||||||
|
@ -178,8 +178,8 @@ namespace Microsoft.Interop
|
||||||
if (toManaged is not null)
|
if (toManaged is not null)
|
||||||
shape |= MarshallerShape.ToManaged;
|
shape |= MarshallerShape.ToManaged;
|
||||||
|
|
||||||
IMethodSymbol? toManagedGuaranteed = Value.ConvertToManagedGuaranteed(marshallerType, managedType);
|
IMethodSymbol? toManagedFinally = Value.ConvertToManagedFinally(marshallerType, managedType);
|
||||||
if (toManagedGuaranteed is not null)
|
if (toManagedFinally is not null)
|
||||||
shape |= MarshallerShape.GuaranteedUnmarshal;
|
shape |= MarshallerShape.GuaranteedUnmarshal;
|
||||||
|
|
||||||
methods = methods with
|
methods = methods with
|
||||||
|
@ -187,7 +187,7 @@ namespace Microsoft.Interop
|
||||||
ToUnmanaged = toUnmanaged,
|
ToUnmanaged = toUnmanaged,
|
||||||
ToUnmanagedWithBuffer = toUnmanagedWithBuffer,
|
ToUnmanagedWithBuffer = toUnmanagedWithBuffer,
|
||||||
ToManaged = toManaged,
|
ToManaged = toManaged,
|
||||||
ToManagedGuaranteed = toManagedGuaranteed
|
ToManagedFinally = toManagedFinally
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,10 +275,10 @@ namespace Microsoft.Interop
|
||||||
&& SymbolEqualityComparer.Default.Equals(managedType, m.ReturnType));
|
&& SymbolEqualityComparer.Default.Equals(managedType, m.ReturnType));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static IMethodSymbol? ConvertToManagedGuaranteed(ITypeSymbol type, ITypeSymbol managedType)
|
internal static IMethodSymbol? ConvertToManagedFinally(ITypeSymbol type, ITypeSymbol managedType)
|
||||||
{
|
{
|
||||||
// static TManaged ConvertToManagedGuaranteed(TNative unmanaged)
|
// static TManaged ConvertToManagedFinally(TNative unmanaged)
|
||||||
return type.GetMembers(ShapeMemberNames.Value.Stateless.ConvertToManagedGuaranteed)
|
return type.GetMembers(ShapeMemberNames.Value.Stateless.ConvertToManagedFinally)
|
||||||
.OfType<IMethodSymbol>()
|
.OfType<IMethodSymbol>()
|
||||||
.FirstOrDefault(m => m is { IsStatic: true, Parameters.Length: 1, ReturnsVoid: false }
|
.FirstOrDefault(m => m is { IsStatic: true, Parameters.Length: 1, ReturnsVoid: false }
|
||||||
&& SymbolEqualityComparer.Default.Equals(managedType, m.ReturnType));
|
&& SymbolEqualityComparer.Default.Equals(managedType, m.ReturnType));
|
||||||
|
@ -349,9 +349,9 @@ namespace Microsoft.Interop
|
||||||
&& managedType.IsConstructedFromEqualTypes(m.ReturnType));
|
&& managedType.IsConstructedFromEqualTypes(m.ReturnType));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static IMethodSymbol? AllocateContainerForManagedElementsGuaranteed(ITypeSymbol type, ITypeSymbol managedType, ITypeSymbol spanOfT)
|
internal static IMethodSymbol? AllocateContainerForManagedElementsFinally(ITypeSymbol type, ITypeSymbol managedType, ITypeSymbol spanOfT)
|
||||||
{
|
{
|
||||||
// static TCollection AllocateContainerForManagedElementsGuaranteed(TNative unmanaged, int length);
|
// static TCollection AllocateContainerForManagedElementsFinally(TNative unmanaged, int length);
|
||||||
return type.GetMembers(ShapeMemberNames.LinearCollection.Stateless.AllocateContainerForManagedElements)
|
return type.GetMembers(ShapeMemberNames.LinearCollection.Stateless.AllocateContainerForManagedElements)
|
||||||
.OfType<IMethodSymbol>()
|
.OfType<IMethodSymbol>()
|
||||||
.FirstOrDefault(m => m is { IsStatic: true, Parameters.Length: 2, ReturnsVoid: false }
|
.FirstOrDefault(m => m is { IsStatic: true, Parameters.Length: 2, ReturnsVoid: false }
|
||||||
|
@ -392,7 +392,7 @@ namespace Microsoft.Interop
|
||||||
public IMethodSymbol? FromUnmanaged { get; init; }
|
public IMethodSymbol? FromUnmanaged { get; init; }
|
||||||
public IMethodSymbol? ToUnmanaged { get; init; }
|
public IMethodSymbol? ToUnmanaged { get; init; }
|
||||||
public IMethodSymbol? Free { get; init; }
|
public IMethodSymbol? Free { get; init; }
|
||||||
public IMethodSymbol? NotifyInvokeSucceeded { get; init; }
|
public IMethodSymbol? OnInvoked { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (MarshallerShape shape, MarshallerMethods methods) GetShapeForType(ITypeSymbol marshallerType, ITypeSymbol managedType, Compilation compilation)
|
public static (MarshallerShape shape, MarshallerMethods methods) GetShapeForType(ITypeSymbol marshallerType, ITypeSymbol managedType, Compilation compilation)
|
||||||
|
@ -431,11 +431,11 @@ namespace Microsoft.Interop
|
||||||
}
|
}
|
||||||
|
|
||||||
IMethodSymbol toManaged = GetToManagedMethod(marshallerType, managedType);
|
IMethodSymbol toManaged = GetToManagedMethod(marshallerType, managedType);
|
||||||
IMethodSymbol toManagedGuaranteed = GetToManagedGuaranteedMethod(marshallerType, managedType);
|
IMethodSymbol toManagedFinally = GetToManagedFinallyMethod(marshallerType, managedType);
|
||||||
IMethodSymbol fromUnmanaged = GetFromUnmanagedMethod(marshallerType, unmanagedType);
|
IMethodSymbol fromUnmanaged = GetFromUnmanagedMethod(marshallerType, unmanagedType);
|
||||||
if ((toManaged, toManagedGuaranteed) is not (null, null) && fromUnmanaged is not null)
|
if ((toManaged, toManagedFinally) is not (null, null) && fromUnmanaged is not null)
|
||||||
{
|
{
|
||||||
if (toManagedGuaranteed is not null)
|
if (toManagedFinally is not null)
|
||||||
{
|
{
|
||||||
shape |= MarshallerShape.GuaranteedUnmarshal;
|
shape |= MarshallerShape.GuaranteedUnmarshal;
|
||||||
}
|
}
|
||||||
|
@ -447,7 +447,7 @@ namespace Microsoft.Interop
|
||||||
{
|
{
|
||||||
FromUnmanaged = fromUnmanaged,
|
FromUnmanaged = fromUnmanaged,
|
||||||
ToManaged = toManaged,
|
ToManaged = toManaged,
|
||||||
ToManagedGuranteed = toManagedGuaranteed
|
ToManagedGuranteed = toManagedFinally
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,11 +458,11 @@ namespace Microsoft.Interop
|
||||||
methods = methods with { Free = free };
|
methods = methods with { Free = free };
|
||||||
}
|
}
|
||||||
|
|
||||||
IMethodSymbol notifyInvokeSucceeded = GetNotifyInvokeSucceededMethod(marshallerType);
|
IMethodSymbol OnInvoked = GetOnInvokedMethod(marshallerType);
|
||||||
if (notifyInvokeSucceeded is not null)
|
if (OnInvoked is not null)
|
||||||
{
|
{
|
||||||
shape |= MarshallerShape.NotifyInvokeSucceeded;
|
shape |= MarshallerShape.OnInvoked;
|
||||||
methods = methods with { NotifyInvokeSucceeded = notifyInvokeSucceeded };
|
methods = methods with { OnInvoked = OnInvoked };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetStatelessGetPinnableReference(marshallerType, managedType) is not null)
|
if (GetStatelessGetPinnableReference(marshallerType, managedType) is not null)
|
||||||
|
@ -531,9 +531,9 @@ namespace Microsoft.Interop
|
||||||
&& SymbolEqualityComparer.Default.Equals(managedType, m.ReturnType));
|
&& SymbolEqualityComparer.Default.Equals(managedType, m.ReturnType));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IMethodSymbol? GetToManagedGuaranteedMethod(ITypeSymbol type, ITypeSymbol managedType)
|
private static IMethodSymbol? GetToManagedFinallyMethod(ITypeSymbol type, ITypeSymbol managedType)
|
||||||
{
|
{
|
||||||
return type.GetMembers(ShapeMemberNames.Value.Stateful.ToManagedGuaranteed)
|
return type.GetMembers(ShapeMemberNames.Value.Stateful.ToManagedFinally)
|
||||||
.OfType<IMethodSymbol>()
|
.OfType<IMethodSymbol>()
|
||||||
.FirstOrDefault(m => m is { IsStatic: false, Parameters.Length: 0, ReturnsVoid: false, ReturnsByRef: false, ReturnsByRefReadonly: false }
|
.FirstOrDefault(m => m is { IsStatic: false, Parameters.Length: 0, ReturnsVoid: false, ReturnsByRef: false, ReturnsByRefReadonly: false }
|
||||||
&& SymbolEqualityComparer.Default.Equals(managedType, m.ReturnType));
|
&& SymbolEqualityComparer.Default.Equals(managedType, m.ReturnType));
|
||||||
|
@ -587,9 +587,9 @@ namespace Microsoft.Interop
|
||||||
.FirstOrDefault(m => m is { IsStatic: false, Parameters.Length: 0, ReturnsVoid: true });
|
.FirstOrDefault(m => m is { IsStatic: false, Parameters.Length: 0, ReturnsVoid: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IMethodSymbol? GetNotifyInvokeSucceededMethod(ITypeSymbol type)
|
private static IMethodSymbol? GetOnInvokedMethod(ITypeSymbol type)
|
||||||
{
|
{
|
||||||
return type.GetMembers(ShapeMemberNames.Value.Stateful.NotifyInvokeSucceeded)
|
return type.GetMembers(ShapeMemberNames.Value.Stateful.OnInvoked)
|
||||||
.OfType<IMethodSymbol>()
|
.OfType<IMethodSymbol>()
|
||||||
.FirstOrDefault(m => m is { IsStatic: false, Parameters.Length: 0, ReturnsVoid: true });
|
.FirstOrDefault(m => m is { IsStatic: false, Parameters.Length: 0, ReturnsVoid: true });
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||||
|
|
||||||
namespace Microsoft.Interop
|
namespace Microsoft.Interop
|
||||||
{
|
{
|
||||||
public readonly record struct AttributedMarshallingModelOptions(bool RuntimeMarshallingDisabled, Scenario InScenario, Scenario RefScenario, Scenario OutScenario);
|
public readonly record struct AttributedMarshallingModelOptions(bool RuntimeMarshallingDisabled, MarshalMode InMode, MarshalMode RefMode, MarshalMode OutMode);
|
||||||
|
|
||||||
public class AttributedMarshallingModelGeneratorFactory : IMarshallingGeneratorFactory
|
public class AttributedMarshallingModelGeneratorFactory : IMarshallingGeneratorFactory
|
||||||
{
|
{
|
||||||
|
@ -214,15 +214,15 @@ namespace Microsoft.Interop
|
||||||
CustomTypeMarshallerData marshallerData;
|
CustomTypeMarshallerData marshallerData;
|
||||||
if (info.IsManagedReturnPosition)
|
if (info.IsManagedReturnPosition)
|
||||||
{
|
{
|
||||||
marshallerData = marshalInfo.Marshallers.GetScenarioOrDefault(Options.OutScenario);
|
marshallerData = marshalInfo.Marshallers.GetModeOrDefault(Options.OutMode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
marshallerData = info.RefKind switch
|
marshallerData = info.RefKind switch
|
||||||
{
|
{
|
||||||
RefKind.None or RefKind.In => marshalInfo.Marshallers.GetScenarioOrDefault(Options.InScenario),
|
RefKind.None or RefKind.In => marshalInfo.Marshallers.GetModeOrDefault(Options.InMode),
|
||||||
RefKind.Ref => marshalInfo.Marshallers.GetScenarioOrDefault(Options.RefScenario),
|
RefKind.Ref => marshalInfo.Marshallers.GetModeOrDefault(Options.RefMode),
|
||||||
RefKind.Out => marshalInfo.Marshallers.GetScenarioOrDefault(Options.OutScenario),
|
RefKind.Out => marshalInfo.Marshallers.GetModeOrDefault(Options.OutMode),
|
||||||
_ => throw new MarshallingNotSupportedException(info, context)
|
_ => throw new MarshallingNotSupportedException(info, context)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -334,7 +334,7 @@ namespace Microsoft.Interop
|
||||||
{
|
{
|
||||||
// Marshalling out or return parameter, but no out marshaller is specified
|
// Marshalling out or return parameter, but no out marshaller is specified
|
||||||
if ((info.RefKind == RefKind.Out || info.IsManagedReturnPosition)
|
if ((info.RefKind == RefKind.Out || info.IsManagedReturnPosition)
|
||||||
&& !marshalInfo.Marshallers.IsDefinedOrDefault(Options.OutScenario))
|
&& !marshalInfo.Marshallers.IsDefinedOrDefault(Options.OutMode))
|
||||||
{
|
{
|
||||||
throw new MarshallingNotSupportedException(info, context)
|
throw new MarshallingNotSupportedException(info, context)
|
||||||
{
|
{
|
||||||
|
@ -343,7 +343,7 @@ namespace Microsoft.Interop
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marshalling ref parameter, but no ref marshaller is specified
|
// Marshalling ref parameter, but no ref marshaller is specified
|
||||||
if (info.RefKind == RefKind.Ref && !marshalInfo.Marshallers.IsDefinedOrDefault(Options.RefScenario))
|
if (info.RefKind == RefKind.Ref && !marshalInfo.Marshallers.IsDefinedOrDefault(Options.RefMode))
|
||||||
{
|
{
|
||||||
throw new MarshallingNotSupportedException(info, context)
|
throw new MarshallingNotSupportedException(info, context)
|
||||||
{
|
{
|
||||||
|
@ -353,7 +353,7 @@ namespace Microsoft.Interop
|
||||||
|
|
||||||
// Marshalling in parameter, but no in marshaller is specified
|
// Marshalling in parameter, but no in marshaller is specified
|
||||||
if (info.RefKind == RefKind.In
|
if (info.RefKind == RefKind.In
|
||||||
&& !marshalInfo.Marshallers.IsDefinedOrDefault(Options.InScenario))
|
&& !marshalInfo.Marshallers.IsDefinedOrDefault(Options.InMode))
|
||||||
{
|
{
|
||||||
throw new MarshallingNotSupportedException(info, context)
|
throw new MarshallingNotSupportedException(info, context)
|
||||||
{
|
{
|
||||||
|
@ -365,7 +365,7 @@ namespace Microsoft.Interop
|
||||||
if (!info.IsByRef
|
if (!info.IsByRef
|
||||||
&& !info.IsManagedReturnPosition
|
&& !info.IsManagedReturnPosition
|
||||||
&& context.SingleFrameSpansNativeContext
|
&& context.SingleFrameSpansNativeContext
|
||||||
&& !(marshalInfo.IsPinnableManagedType || marshalInfo.Marshallers.IsDefinedOrDefault(Options.InScenario)))
|
&& !(marshalInfo.IsPinnableManagedType || marshalInfo.Marshallers.IsDefinedOrDefault(Options.InMode)))
|
||||||
{
|
{
|
||||||
throw new MarshallingNotSupportedException(info, context)
|
throw new MarshallingNotSupportedException(info, context)
|
||||||
{
|
{
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace Microsoft.Interop
|
||||||
|
|
||||||
(string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info);
|
(string managedIdentifier, string nativeIdentifier) = context.GetIdentifiers(info);
|
||||||
|
|
||||||
// <managedIdentifier> = <marshallerType>.ConvertToManagedGuaranteed(<nativeIdentifier>);
|
// <managedIdentifier> = <marshallerType>.ConvertToManagedFinally(<nativeIdentifier>);
|
||||||
yield return ExpressionStatement(
|
yield return ExpressionStatement(
|
||||||
AssignmentExpression(
|
AssignmentExpression(
|
||||||
SyntaxKind.SimpleAssignmentExpression,
|
SyntaxKind.SimpleAssignmentExpression,
|
||||||
|
@ -82,7 +82,7 @@ namespace Microsoft.Interop
|
||||||
InvocationExpression(
|
InvocationExpression(
|
||||||
MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
|
MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
|
||||||
_marshallerTypeSyntax,
|
_marshallerTypeSyntax,
|
||||||
IdentifierName(ShapeMemberNames.Value.Stateless.ConvertToManagedGuaranteed)),
|
IdentifierName(ShapeMemberNames.Value.Stateless.ConvertToManagedFinally)),
|
||||||
ArgumentList(SingletonSeparatedList(
|
ArgumentList(SingletonSeparatedList(
|
||||||
Argument(IdentifierName(nativeIdentifier)))))));
|
Argument(IdentifierName(nativeIdentifier)))))));
|
||||||
}
|
}
|
||||||
|
@ -324,7 +324,7 @@ namespace Microsoft.Interop
|
||||||
|
|
||||||
(string managedIdentifier, _) = context.GetIdentifiers(info);
|
(string managedIdentifier, _) = context.GetIdentifiers(info);
|
||||||
|
|
||||||
// <managedIdentifier> = <marshaller>.ToManagedGuaranteed();
|
// <managedIdentifier> = <marshaller>.ToManagedFinally();
|
||||||
yield return ExpressionStatement(
|
yield return ExpressionStatement(
|
||||||
AssignmentExpression(
|
AssignmentExpression(
|
||||||
SyntaxKind.SimpleAssignmentExpression,
|
SyntaxKind.SimpleAssignmentExpression,
|
||||||
|
@ -332,7 +332,7 @@ namespace Microsoft.Interop
|
||||||
InvocationExpression(
|
InvocationExpression(
|
||||||
MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
|
MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
|
||||||
IdentifierName(context.GetAdditionalIdentifier(info, MarshallerIdentifier)),
|
IdentifierName(context.GetAdditionalIdentifier(info, MarshallerIdentifier)),
|
||||||
IdentifierName(ShapeMemberNames.Value.Stateful.ToManagedGuaranteed)),
|
IdentifierName(ShapeMemberNames.Value.Stateful.ToManagedFinally)),
|
||||||
ArgumentList())));
|
ArgumentList())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,15 +438,15 @@ namespace Microsoft.Interop
|
||||||
|
|
||||||
public IEnumerable<StatementSyntax> GenerateNotifyForSuccessfulInvokeStatements(TypePositionInfo info, StubCodeContext context)
|
public IEnumerable<StatementSyntax> GenerateNotifyForSuccessfulInvokeStatements(TypePositionInfo info, StubCodeContext context)
|
||||||
{
|
{
|
||||||
if (!_shape.HasFlag(MarshallerShape.NotifyInvokeSucceeded))
|
if (!_shape.HasFlag(MarshallerShape.OnInvoked))
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
// <marshaller>.NotifyInvokeSucceeded();
|
// <marshaller>.OnInvoked();
|
||||||
yield return ExpressionStatement(
|
yield return ExpressionStatement(
|
||||||
InvocationExpression(
|
InvocationExpression(
|
||||||
MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
|
MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
|
||||||
IdentifierName(context.GetAdditionalIdentifier(info, MarshallerIdentifier)),
|
IdentifierName(context.GetAdditionalIdentifier(info, MarshallerIdentifier)),
|
||||||
IdentifierName(ShapeMemberNames.Value.Stateful.NotifyInvokeSucceeded)),
|
IdentifierName(ShapeMemberNames.Value.Stateful.OnInvoked)),
|
||||||
ArgumentList()));
|
ArgumentList()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -627,7 +627,7 @@ namespace Microsoft.Interop
|
||||||
else if (type is INamedTypeSymbol namedManagedType)
|
else if (type is INamedTypeSymbol namedManagedType)
|
||||||
{
|
{
|
||||||
// Entry point type for linear collection marshalling must have the arity of the managed type + 1
|
// Entry point type for linear collection marshalling must have the arity of the managed type + 1
|
||||||
// for the [ElementUnmanagedType] placeholder
|
// for the element unmanaged type placeholder
|
||||||
if (entryPointType.Arity != namedManagedType.Arity + 1)
|
if (entryPointType.Arity != namedManagedType.Arity + 1)
|
||||||
{
|
{
|
||||||
_diagnostics.ReportInvalidMarshallingAttributeInfo(attrData, nameof(SR.MarshallerEntryPointTypeMustMatchArity), entryPointType.ToDisplayString(), type.ToDisplayString());
|
_diagnostics.ReportInvalidMarshallingAttributeInfo(attrData, nameof(SR.MarshallerEntryPointTypeMustMatchArity), entryPointType.ToDisplayString(), type.ToDisplayString());
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
Link="Production\CustomTypeMarshallerFeatures.cs" />
|
Link="Production\CustomTypeMarshallerFeatures.cs" />
|
||||||
<Compile Include="$(CoreLibSharedDir)System\Runtime\InteropServices\StringMarshalling.cs"
|
<Compile Include="$(CoreLibSharedDir)System\Runtime\InteropServices\StringMarshalling.cs"
|
||||||
Link="Production\StringMarshalling.cs" />
|
Link="Production\StringMarshalling.cs" />
|
||||||
<Compile Include="..\..\tests\Ancillary.Interop\Scenario.cs"
|
<Compile Include="$(CoreLibSharedDir)\System\Runtime\InteropServices\Marshalling\MarshalMode.cs"
|
||||||
Link="Production\Scenario.cs" />
|
Link="Production\MarshalMode.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace Microsoft.Interop
|
||||||
|
|
||||||
public const string CustomMarshallerAttribute = "System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute";
|
public const string CustomMarshallerAttribute = "System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute";
|
||||||
public const string CustomMarshallerAttributeGenericPlaceholder = CustomMarshallerAttribute + ".GenericPlaceholder";
|
public const string CustomMarshallerAttributeGenericPlaceholder = CustomMarshallerAttribute + ".GenericPlaceholder";
|
||||||
public const string ElementUnmanagedTypeAttribute = "System.Runtime.InteropServices.Marshalling.ElementUnmanagedTypeAttribute";
|
public const string ContiguousCollectionMarshallerAttribute = "System.Runtime.InteropServices.Marshalling.ContiguousCollectionMarshallerAttribute";
|
||||||
|
|
||||||
public const string AnsiStringMarshaller = "System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller";
|
public const string AnsiStringMarshaller = "System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller";
|
||||||
public const string BStrStringMarshaller = "System.Runtime.InteropServices.Marshalling.BStrStringMarshaller";
|
public const string BStrStringMarshaller = "System.Runtime.InteropServices.Marshalling.BStrStringMarshaller";
|
||||||
|
|
|
@ -2169,6 +2169,19 @@ namespace System.Runtime.InteropServices.Marshalling
|
||||||
public string? ToManaged() { throw null; }
|
public string? ToManaged() { throw null; }
|
||||||
public void FreeNative() { }
|
public void FreeNative() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[System.AttributeUsageAttribute(System.AttributeTargets.Struct | System.AttributeTargets.Class, AllowMultiple = true)]
|
||||||
|
public sealed partial class CustomMarshallerAttribute : System.Attribute
|
||||||
|
{
|
||||||
|
public CustomMarshallerAttribute(System.Type managedType, System.Runtime.InteropServices.Marshalling.MarshalMode marshalMode, System.Type marshallerType) { }
|
||||||
|
public System.Type ManagedType { get { throw null; } }
|
||||||
|
public System.Runtime.InteropServices.Marshalling.MarshalMode MarshalMode { get { throw null; } }
|
||||||
|
public System.Type MarshallerType { get { throw null; } }
|
||||||
|
public struct GenericPlaceholder
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[System.AttributeUsageAttribute(System.AttributeTargets.Struct)]
|
[System.AttributeUsageAttribute(System.AttributeTargets.Struct)]
|
||||||
public sealed partial class CustomTypeMarshallerAttribute : System.Attribute
|
public sealed partial class CustomTypeMarshallerAttribute : System.Attribute
|
||||||
{
|
{
|
||||||
|
@ -2204,6 +2217,19 @@ namespace System.Runtime.InteropServices.Marshalling
|
||||||
Value,
|
Value,
|
||||||
LinearCollection
|
LinearCollection
|
||||||
}
|
}
|
||||||
|
public enum MarshalMode
|
||||||
|
{
|
||||||
|
Default = 0,
|
||||||
|
ManagedToUnmanagedIn = 1,
|
||||||
|
ManagedToUnmanagedRef = 2,
|
||||||
|
ManagedToUnmanagedOut = 3,
|
||||||
|
UnmanagedToManagedIn = 4,
|
||||||
|
UnmanagedToManagedRef = 5,
|
||||||
|
UnmanagedToManagedOut = 6,
|
||||||
|
ElementIn = 7,
|
||||||
|
ElementRef = 8,
|
||||||
|
ElementOut = 9
|
||||||
|
}
|
||||||
[System.AttributeUsageAttribute(System.AttributeTargets.Parameter | System.AttributeTargets.ReturnValue, AllowMultiple = true)]
|
[System.AttributeUsageAttribute(System.AttributeTargets.Parameter | System.AttributeTargets.ReturnValue, AllowMultiple = true)]
|
||||||
public sealed partial class MarshalUsingAttribute : System.Attribute
|
public sealed partial class MarshalUsingAttribute : System.Attribute
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
|
||||||
|
namespace System.Runtime.InteropServices.Marshalling
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies that this marshaller entry-point type is a contiguous collection marshaller.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
||||||
|
public sealed class ContiguousCollectionMarshallerAttribute : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,35 +0,0 @@
|
||||||
// Licensed to the .NET Foundation under one or more agreements.
|
|
||||||
// The .NET Foundation licenses this file to you under the MIT license.
|
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace System.Runtime.InteropServices.Marshalling
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Attribute to indicate an entry point type for defining a marshaller.
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
|
||||||
#if LIBRARYIMPORT_GENERATOR_TEST
|
|
||||||
public
|
|
||||||
#else
|
|
||||||
internal
|
|
||||||
#endif
|
|
||||||
sealed class CustomMarshallerAttribute : Attribute
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Create a <see cref="CustomMarshallerAttribute"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="managedType">Managed type to marshal.</param>
|
|
||||||
/// <param name="scenario">Marshalling scenario.</param>
|
|
||||||
/// <param name="marshallerType">Type used for marshalling.</param>
|
|
||||||
public CustomMarshallerAttribute(Type managedType, Scenario scenario, Type marshallerType) { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Placeholder type for generic parameter
|
|
||||||
/// </summary>
|
|
||||||
public struct GenericPlaceholder
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
// Licensed to the .NET Foundation under one or more agreements.
|
|
||||||
// The .NET Foundation licenses this file to you under the MIT license.
|
|
||||||
|
|
||||||
namespace System.Runtime.InteropServices.Marshalling
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies that a particular generic parameter is the collection element's unmanaged type.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// If this attribute is provided on a generic parameter of a marshaller, then the generator will assume
|
|
||||||
/// that it is a linear collection marshaller.
|
|
||||||
/// </remarks>
|
|
||||||
[AttributeUsage(AttributeTargets.GenericParameter)]
|
|
||||||
public sealed class ElementUnmanagedTypeAttribute : Attribute
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -47,19 +47,19 @@ namespace LibraryImportGenerator.IntegrationTests
|
||||||
[return: MarshalUsing(typeof(IntGuaranteedUnmarshal))]
|
[return: MarshalUsing(typeof(IntGuaranteedUnmarshal))]
|
||||||
public static partial int GuaranteedUnmarshal([MarshalUsing(typeof(ExceptionOnUnmarshal))] out int ret);
|
public static partial int GuaranteedUnmarshal([MarshalUsing(typeof(ExceptionOnUnmarshal))] out int ret);
|
||||||
|
|
||||||
[CustomMarshaller(typeof(int), Scenario.ManagedToUnmanagedOut, typeof(ExceptionOnUnmarshal))]
|
[CustomMarshaller(typeof(int), MarshalMode.ManagedToUnmanagedOut, typeof(ExceptionOnUnmarshal))]
|
||||||
public static class ExceptionOnUnmarshal
|
public static class ExceptionOnUnmarshal
|
||||||
{
|
{
|
||||||
public static int ConvertToManaged(int unmanaged) => throw new Exception();
|
public static int ConvertToManaged(int unmanaged) => throw new Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(int), Scenario.ManagedToUnmanagedOut, typeof(IntGuaranteedUnmarshal))]
|
[CustomMarshaller(typeof(int), MarshalMode.ManagedToUnmanagedOut, typeof(IntGuaranteedUnmarshal))]
|
||||||
public static unsafe class IntGuaranteedUnmarshal
|
public static unsafe class IntGuaranteedUnmarshal
|
||||||
{
|
{
|
||||||
public static bool ConvertToManagedGuaranteedCalled = false;
|
public static bool ConvertToManagedFinallyCalled = false;
|
||||||
public static int ConvertToManagedGuaranteed(int unmanaged)
|
public static int ConvertToManagedFinally(int unmanaged)
|
||||||
{
|
{
|
||||||
ConvertToManagedGuaranteedCalled = true;
|
ConvertToManagedFinallyCalled = true;
|
||||||
return unmanaged;
|
return unmanaged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,9 +134,9 @@ namespace LibraryImportGenerator.IntegrationTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GuaranteedUnmarshal()
|
public void GuaranteedUnmarshal()
|
||||||
{
|
{
|
||||||
NativeExportsNE.Stateless.IntGuaranteedUnmarshal.ConvertToManagedGuaranteedCalled = false;
|
NativeExportsNE.Stateless.IntGuaranteedUnmarshal.ConvertToManagedFinallyCalled = false;
|
||||||
Assert.Throws<Exception>(() => NativeExportsNE.Stateless.GuaranteedUnmarshal(out _));
|
Assert.Throws<Exception>(() => NativeExportsNE.Stateless.GuaranteedUnmarshal(out _));
|
||||||
Assert.True(NativeExportsNE.Stateless.IntGuaranteedUnmarshal.ConvertToManagedGuaranteedCalled);
|
Assert.True(NativeExportsNE.Stateless.IntGuaranteedUnmarshal.ConvertToManagedFinallyCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -240,7 +240,7 @@ namespace LibraryImportGenerator.IntegrationTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void NotifyInvokeSucceededInNoReturn()
|
public void OnInvokedInNoReturn()
|
||||||
{
|
{
|
||||||
bool xNotified = false;
|
bool xNotified = false;
|
||||||
bool yNotified = false;
|
bool yNotified = false;
|
||||||
|
@ -260,7 +260,7 @@ namespace LibraryImportGenerator.IntegrationTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void NotifyInvokeSucceededInNoOut()
|
public void OnInvokedInNoOut()
|
||||||
{
|
{
|
||||||
bool xNotified = false;
|
bool xNotified = false;
|
||||||
bool yNotified = false;
|
bool yNotified = false;
|
||||||
|
|
|
@ -690,7 +690,7 @@ public struct S
|
||||||
}}
|
}}
|
||||||
";
|
";
|
||||||
private static string NonStatic = @"
|
private static string NonStatic = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedIn, typeof(Marshaller))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedIn, typeof(Marshaller))]
|
||||||
public class Marshaller
|
public class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -705,7 +705,7 @@ public class Marshaller
|
||||||
public static class Stateless
|
public static class Stateless
|
||||||
{
|
{
|
||||||
private static string In = @"
|
private static string In = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedIn, typeof(Marshaller))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedIn, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -714,7 +714,7 @@ public static class Marshaller
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
private static string InBuffer = @"
|
private static string InBuffer = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedIn, typeof(Marshaller))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedIn, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -725,7 +725,7 @@ public static class Marshaller
|
||||||
";
|
";
|
||||||
|
|
||||||
public static string InPinnable = @"
|
public static string InPinnable = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedIn, typeof(Marshaller))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedIn, typeof(Marshaller))]
|
||||||
public static unsafe class Marshaller
|
public static unsafe class Marshaller
|
||||||
{
|
{
|
||||||
public static byte* ConvertToUnmanaged(S s) => default;
|
public static byte* ConvertToUnmanaged(S s) => default;
|
||||||
|
@ -733,7 +733,7 @@ public static unsafe class Marshaller
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
private static string Out = @"
|
private static string Out = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedOut, typeof(Marshaller))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedOut, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -742,16 +742,16 @@ public static class Marshaller
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
private static string OutGuaranteed = @"
|
private static string OutGuaranteed = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedOut, typeof(Marshaller))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedOut, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
|
||||||
public static S ConvertToManagedGuaranteed(Native n) => default;
|
public static S ConvertToManagedFinally(Native n) => default;
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public static string Ref = @"
|
public static string Ref = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.Default, typeof(Marshaller))]
|
[CustomMarshaller(typeof(S), MarshalMode.Default, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -761,8 +761,8 @@ public static class Marshaller
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public static string RefBuffer = @"
|
public static string RefBuffer = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedIn, typeof(Marshaller))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedIn, typeof(Marshaller))]
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedOut, typeof(Marshaller))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedOut, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -773,7 +773,7 @@ public static class Marshaller
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public static string RefOptionalBuffer = @"
|
public static string RefOptionalBuffer = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.Default, typeof(Marshaller))]
|
[CustomMarshaller(typeof(S), MarshalMode.Default, typeof(Marshaller))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -793,7 +793,7 @@ public static class Marshaller
|
||||||
+ NonBlittableUserDefinedType()
|
+ NonBlittableUserDefinedType()
|
||||||
+ Out;
|
+ Out;
|
||||||
|
|
||||||
public static string NativeToManagedGuaranteedOnlyOutParameter => BasicParameterWithByRefModifier("out", "S")
|
public static string NativeToManagedFinallyOnlyOutParameter => BasicParameterWithByRefModifier("out", "S")
|
||||||
+ NonBlittableUserDefinedType()
|
+ NonBlittableUserDefinedType()
|
||||||
+ OutGuaranteed;
|
+ OutGuaranteed;
|
||||||
|
|
||||||
|
@ -805,7 +805,7 @@ public static class Marshaller
|
||||||
+ NonBlittableUserDefinedType()
|
+ NonBlittableUserDefinedType()
|
||||||
+ Out;
|
+ Out;
|
||||||
|
|
||||||
public static string NativeToManagedGuaranteedOnlyReturnValue => BasicReturnType("S")
|
public static string NativeToManagedFinallyOnlyReturnValue => BasicReturnType("S")
|
||||||
+ NonBlittableUserDefinedType()
|
+ NonBlittableUserDefinedType()
|
||||||
+ Out;
|
+ Out;
|
||||||
|
|
||||||
|
@ -844,7 +844,7 @@ public static class Marshaller
|
||||||
public static class Stateful
|
public static class Stateful
|
||||||
{
|
{
|
||||||
private static string In = @"
|
private static string In = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedIn, typeof(M))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedIn, typeof(M))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -858,7 +858,7 @@ public static class Marshaller
|
||||||
";
|
";
|
||||||
|
|
||||||
public static string InStatelessPinnable = @"
|
public static string InStatelessPinnable = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedIn, typeof(M))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedIn, typeof(M))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public unsafe struct M
|
public unsafe struct M
|
||||||
|
@ -872,7 +872,7 @@ public static class Marshaller
|
||||||
";
|
";
|
||||||
|
|
||||||
public static string InPinnable = @"
|
public static string InPinnable = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedIn, typeof(M))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedIn, typeof(M))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public unsafe struct M
|
public unsafe struct M
|
||||||
|
@ -886,7 +886,7 @@ public static class Marshaller
|
||||||
";
|
";
|
||||||
|
|
||||||
private static string InBuffer = @"
|
private static string InBuffer = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedIn, typeof(M))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedIn, typeof(M))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -900,7 +900,7 @@ public static class Marshaller
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
private static string Out = @"
|
private static string Out = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedOut, typeof(M))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedOut, typeof(M))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -913,7 +913,7 @@ public static class Marshaller
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
private static string OutGuaranteed = @"
|
private static string OutGuaranteed = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedOut, typeof(M))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedOut, typeof(M))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -921,12 +921,12 @@ public static class Marshaller
|
||||||
public struct M
|
public struct M
|
||||||
{
|
{
|
||||||
public void FromUnmanaged(Native n) {}
|
public void FromUnmanaged(Native n) {}
|
||||||
public S ToManagedGuaranteed() => default;
|
public S ToManagedFinally() => default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public static string Ref = @"
|
public static string Ref = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.Default, typeof(M))]
|
[CustomMarshaller(typeof(S), MarshalMode.Default, typeof(M))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -941,7 +941,7 @@ public static class Marshaller
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public static string RefWithFree = @"
|
public static string RefWithFree = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.Default, typeof(M))]
|
[CustomMarshaller(typeof(S), MarshalMode.Default, typeof(M))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -956,8 +956,8 @@ public static class Marshaller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public static string RefWithNotifyInvokeSucceeded = @"
|
public static string RefWithOnInvoked = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.Default, typeof(M))]
|
[CustomMarshaller(typeof(S), MarshalMode.Default, typeof(M))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -968,13 +968,13 @@ public static class Marshaller
|
||||||
public Native ToUnmanaged() => default;
|
public Native ToUnmanaged() => default;
|
||||||
public void FromUnmanaged(Native n) {}
|
public void FromUnmanaged(Native n) {}
|
||||||
public S ToManaged() => default;
|
public S ToManaged() => default;
|
||||||
public void NotifyInvokeSucceeded() {}
|
public void OnInvoked() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public static string RefBuffer = @"
|
public static string RefBuffer = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedIn, typeof(M))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedIn, typeof(M))]
|
||||||
[CustomMarshaller(typeof(S), Scenario.ManagedToUnmanagedOut, typeof(M))]
|
[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedOut, typeof(M))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -990,7 +990,7 @@ public static class Marshaller
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public static string RefOptionalBuffer = @"
|
public static string RefOptionalBuffer = @"
|
||||||
[CustomMarshaller(typeof(S), Scenario.Default, typeof(M))]
|
[CustomMarshaller(typeof(S), MarshalMode.Default, typeof(M))]
|
||||||
public static class Marshaller
|
public static class Marshaller
|
||||||
{
|
{
|
||||||
public struct Native { }
|
public struct Native { }
|
||||||
|
@ -1015,7 +1015,7 @@ public static class Marshaller
|
||||||
+ NonBlittableUserDefinedType()
|
+ NonBlittableUserDefinedType()
|
||||||
+ Out;
|
+ Out;
|
||||||
|
|
||||||
public static string NativeToManagedGuaranteedOnlyOutParameter => BasicParameterWithByRefModifier("out", "S")
|
public static string NativeToManagedFinallyOnlyOutParameter => BasicParameterWithByRefModifier("out", "S")
|
||||||
+ NonBlittableUserDefinedType()
|
+ NonBlittableUserDefinedType()
|
||||||
+ OutGuaranteed;
|
+ OutGuaranteed;
|
||||||
|
|
||||||
|
@ -1027,7 +1027,7 @@ public static class Marshaller
|
||||||
+ NonBlittableUserDefinedType()
|
+ NonBlittableUserDefinedType()
|
||||||
+ Out;
|
+ Out;
|
||||||
|
|
||||||
public static string NativeToManagedGuaranteedOnlyReturnValue => BasicReturnType("S")
|
public static string NativeToManagedFinallyOnlyReturnValue => BasicReturnType("S")
|
||||||
+ NonBlittableUserDefinedType()
|
+ NonBlittableUserDefinedType()
|
||||||
+ Out;
|
+ Out;
|
||||||
|
|
||||||
|
@ -1043,9 +1043,9 @@ public static class Marshaller
|
||||||
+ NonBlittableUserDefinedType(defineNativeMarshalling: true)
|
+ NonBlittableUserDefinedType(defineNativeMarshalling: true)
|
||||||
+ RefWithFree;
|
+ RefWithFree;
|
||||||
|
|
||||||
public static string ParametersAndModifiersWithNotifyInvokeSucceeded = BasicParametersAndModifiers("S", UsingSystemRuntimeInteropServicesMarshalling)
|
public static string ParametersAndModifiersWithOnInvoked = BasicParametersAndModifiers("S", UsingSystemRuntimeInteropServicesMarshalling)
|
||||||
+ NonBlittableUserDefinedType(defineNativeMarshalling: true)
|
+ NonBlittableUserDefinedType(defineNativeMarshalling: true)
|
||||||
+ RefWithNotifyInvokeSucceeded;
|
+ RefWithOnInvoked;
|
||||||
|
|
||||||
public static string MarshalUsingParametersAndModifiers = MarshalUsingParametersAndModifiers("S", "Marshaller")
|
public static string MarshalUsingParametersAndModifiers = MarshalUsingParametersAndModifiers("S", "Marshaller")
|
||||||
+ NonBlittableUserDefinedType(defineNativeMarshalling: false)
|
+ NonBlittableUserDefinedType(defineNativeMarshalling: false)
|
||||||
|
@ -1457,8 +1457,9 @@ partial class Test
|
||||||
public static class Stateless
|
public static class Stateless
|
||||||
{
|
{
|
||||||
public const string In = @"
|
public const string In = @"
|
||||||
[CustomMarshaller(typeof(TestCollection<>), Scenario.ManagedToUnmanagedIn, typeof(Marshaller<,>))]
|
[CustomMarshaller(typeof(TestCollection<>), MarshalMode.ManagedToUnmanagedIn, typeof(Marshaller<,>))]
|
||||||
static unsafe class Marshaller<T, [ElementUnmanagedType] TUnmanagedElement>
|
[ContiguousCollectionMarshaller]
|
||||||
|
static unsafe class Marshaller<T, TUnmanagedElement>
|
||||||
{
|
{
|
||||||
public static byte* AllocateContainerForUnmanagedElements(TestCollection<T> managed, out int numElements) => throw null;
|
public static byte* AllocateContainerForUnmanagedElements(TestCollection<T> managed, out int numElements) => throw null;
|
||||||
public static System.ReadOnlySpan<T> GetManagedValuesSource(TestCollection<T> managed) => throw null;
|
public static System.ReadOnlySpan<T> GetManagedValuesSource(TestCollection<T> managed) => throw null;
|
||||||
|
@ -1466,8 +1467,9 @@ static unsafe class Marshaller<T, [ElementUnmanagedType] TUnmanagedElement>
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public const string InPinnable = @"
|
public const string InPinnable = @"
|
||||||
[CustomMarshaller(typeof(TestCollection<>), Scenario.ManagedToUnmanagedIn, typeof(Marshaller<,>))]
|
[CustomMarshaller(typeof(TestCollection<>), MarshalMode.ManagedToUnmanagedIn, typeof(Marshaller<,>))]
|
||||||
static unsafe class Marshaller<T, [ElementUnmanagedType] TUnmanagedElement>
|
[ContiguousCollectionMarshaller]
|
||||||
|
static unsafe class Marshaller<T, TUnmanagedElement>
|
||||||
{
|
{
|
||||||
public static byte* AllocateContainerForUnmanagedElements(TestCollection<T> managed, out int numElements) => throw null;
|
public static byte* AllocateContainerForUnmanagedElements(TestCollection<T> managed, out int numElements) => throw null;
|
||||||
public static System.ReadOnlySpan<T> GetManagedValuesSource(TestCollection<T> managed) => throw null;
|
public static System.ReadOnlySpan<T> GetManagedValuesSource(TestCollection<T> managed) => throw null;
|
||||||
|
@ -1477,8 +1479,9 @@ static unsafe class Marshaller<T, [ElementUnmanagedType] TUnmanagedElement>
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public const string InBuffer = @"
|
public const string InBuffer = @"
|
||||||
[CustomMarshaller(typeof(TestCollection<>), Scenario.ManagedToUnmanagedIn, typeof(Marshaller<,>))]
|
[CustomMarshaller(typeof(TestCollection<>), MarshalMode.ManagedToUnmanagedIn, typeof(Marshaller<,>))]
|
||||||
static unsafe class Marshaller<T, [ElementUnmanagedType] TUnmanagedElement>
|
[ContiguousCollectionMarshaller]
|
||||||
|
static unsafe class Marshaller<T, TUnmanagedElement>
|
||||||
{
|
{
|
||||||
public const int BufferSize = 0x100;
|
public const int BufferSize = 0x100;
|
||||||
public static byte* AllocateContainerForUnmanagedElements(TestCollection<T> managed, System.Span<byte> buffer, out int numElements) => throw null;
|
public static byte* AllocateContainerForUnmanagedElements(TestCollection<T> managed, System.Span<byte> buffer, out int numElements) => throw null;
|
||||||
|
@ -1487,8 +1490,9 @@ static unsafe class Marshaller<T, [ElementUnmanagedType] TUnmanagedElement>
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public const string Ref = @"
|
public const string Ref = @"
|
||||||
[CustomMarshaller(typeof(TestCollection<>), Scenario.Default, typeof(Marshaller<,>))]
|
[CustomMarshaller(typeof(TestCollection<>), MarshalMode.Default, typeof(Marshaller<,>))]
|
||||||
static unsafe class Marshaller<T, [ElementUnmanagedType] TUnmanagedElement>
|
[ContiguousCollectionMarshaller]
|
||||||
|
static unsafe class Marshaller<T, TUnmanagedElement>
|
||||||
{
|
{
|
||||||
public static byte* AllocateContainerForUnmanagedElements(TestCollection<T> managed, out int numElements) => throw null;
|
public static byte* AllocateContainerForUnmanagedElements(TestCollection<T> managed, out int numElements) => throw null;
|
||||||
public static System.ReadOnlySpan<T> GetManagedValuesSource(TestCollection<T> managed) => throw null;
|
public static System.ReadOnlySpan<T> GetManagedValuesSource(TestCollection<T> managed) => throw null;
|
||||||
|
@ -1500,8 +1504,9 @@ static unsafe class Marshaller<T, [ElementUnmanagedType] TUnmanagedElement>
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public const string RefNested = @"
|
public const string RefNested = @"
|
||||||
[CustomMarshaller(typeof(TestCollection<>), Scenario.Default, typeof(Marshaller<,>.Ref.Nested))]
|
[CustomMarshaller(typeof(TestCollection<>), MarshalMode.Default, typeof(Marshaller<,>.Ref.Nested))]
|
||||||
static unsafe class Marshaller<T, [ElementUnmanagedType] TUnmanagedElement>
|
[ContiguousCollectionMarshaller]
|
||||||
|
static unsafe class Marshaller<T, TUnmanagedElement>
|
||||||
{
|
{
|
||||||
static class Nested
|
static class Nested
|
||||||
{
|
{
|
||||||
|
@ -1519,8 +1524,9 @@ static unsafe class Marshaller<T, [ElementUnmanagedType] TUnmanagedElement>
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
public const string Out = @"
|
public const string Out = @"
|
||||||
[CustomMarshaller(typeof(TestCollection<>), Scenario.ManagedToUnmanagedOut, typeof(Marshaller<,>))]
|
[CustomMarshaller(typeof(TestCollection<>), MarshalMode.ManagedToUnmanagedOut, typeof(Marshaller<,>))]
|
||||||
static unsafe class Marshaller<T, [ElementUnmanagedType] TUnmanagedElement>
|
[ContiguousCollectionMarshaller]
|
||||||
|
static unsafe class Marshaller<T, TUnmanagedElement>
|
||||||
{
|
{
|
||||||
public static TestCollection<T> AllocateContainerForManagedElements(byte* unmanaged, int length) => throw null;
|
public static TestCollection<T> AllocateContainerForManagedElements(byte* unmanaged, int length) => throw null;
|
||||||
public static System.Span<T> GetManagedValuesDestination(TestCollection<T> managed) => throw null;
|
public static System.Span<T> GetManagedValuesDestination(TestCollection<T> managed) => throw null;
|
||||||
|
@ -1577,8 +1583,9 @@ static unsafe class Marshaller<T, [ElementUnmanagedType] TUnmanagedElement>
|
||||||
[NativeMarshalling(typeof(Marshaller<,,>))]
|
[NativeMarshalling(typeof(Marshaller<,,>))]
|
||||||
class TestCollection<T> {}
|
class TestCollection<T> {}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(TestCollection<>), Scenario.Default, typeof(Marshaller<,,>))]
|
[CustomMarshaller(typeof(TestCollection<>), MarshalMode.Default, typeof(Marshaller<,,>))]
|
||||||
static unsafe class Marshaller<T, U, [ElementUnmanagedType] TUnmanagedElement>
|
[ContiguousCollectionMarshaller]
|
||||||
|
static unsafe class Marshaller<T, U, TUnmanagedElement>
|
||||||
{
|
{
|
||||||
public static byte* AllocateContainerForUnmanagedElements(TestCollection<T> managed, out int numElements) => throw null;
|
public static byte* AllocateContainerForUnmanagedElements(TestCollection<T> managed, out int numElements) => throw null;
|
||||||
public static System.ReadOnlySpan<T> GetManagedValuesSource(TestCollection<T> managed) => throw null;
|
public static System.ReadOnlySpan<T> GetManagedValuesSource(TestCollection<T> managed) => throw null;
|
||||||
|
|
|
@ -173,21 +173,21 @@ namespace LibraryImportGenerator.UnitTests
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.ParametersAndModifiers };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.ParametersAndModifiers };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.MarshalUsingParametersAndModifiers };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.MarshalUsingParametersAndModifiers };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.NativeToManagedOnlyOutParameter };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.NativeToManagedOnlyOutParameter };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.NativeToManagedGuaranteedOnlyOutParameter };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.NativeToManagedFinallyOnlyOutParameter };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.NativeToManagedOnlyReturnValue };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.NativeToManagedOnlyReturnValue };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.NativeToManagedGuaranteedOnlyReturnValue };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.NativeToManagedFinallyOnlyReturnValue };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.PinByValueInParameter };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.PinByValueInParameter };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.StackallocByValueInParameter };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.StackallocByValueInParameter };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.StackallocParametersAndModifiersNoRef };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.StackallocParametersAndModifiersNoRef };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.OptionalStackallocParametersAndModifiers };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateless.OptionalStackallocParametersAndModifiers };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.ParametersAndModifiers };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.ParametersAndModifiers };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.ParametersAndModifiersWithFree };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.ParametersAndModifiersWithFree };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.ParametersAndModifiersWithNotifyInvokeSucceeded };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.ParametersAndModifiersWithOnInvoked };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.MarshalUsingParametersAndModifiers };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.MarshalUsingParametersAndModifiers };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.NativeToManagedOnlyOutParameter };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.NativeToManagedOnlyOutParameter };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.NativeToManagedGuaranteedOnlyOutParameter };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.NativeToManagedFinallyOnlyOutParameter };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.NativeToManagedOnlyReturnValue };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.NativeToManagedOnlyReturnValue };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.NativeToManagedGuaranteedOnlyReturnValue };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.NativeToManagedFinallyOnlyReturnValue };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.StackallocByValueInParameter };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.StackallocByValueInParameter };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.PinByValueInParameter };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.PinByValueInParameter };
|
||||||
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.MarshallerPinByValueInParameter };
|
yield return new[] { CodeSnippets.CustomStructMarshalling.Stateful.MarshallerPinByValueInParameter };
|
||||||
|
|
|
@ -20,9 +20,9 @@ namespace SharedTypes
|
||||||
public string str2;
|
public string str2;
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(StringContainer), Scenario.ManagedToUnmanagedIn, typeof(In))]
|
[CustomMarshaller(typeof(StringContainer), MarshalMode.ManagedToUnmanagedIn, typeof(In))]
|
||||||
[CustomMarshaller(typeof(StringContainer), Scenario.ManagedToUnmanagedRef, typeof(Ref))]
|
[CustomMarshaller(typeof(StringContainer), MarshalMode.ManagedToUnmanagedRef, typeof(Ref))]
|
||||||
[CustomMarshaller(typeof(StringContainer), Scenario.ManagedToUnmanagedOut, typeof(Out))]
|
[CustomMarshaller(typeof(StringContainer), MarshalMode.ManagedToUnmanagedOut, typeof(Out))]
|
||||||
public static class StringContainerMarshaller
|
public static class StringContainerMarshaller
|
||||||
{
|
{
|
||||||
public struct StringContainerNative
|
public struct StringContainerNative
|
||||||
|
@ -77,7 +77,7 @@ namespace SharedTypes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(double), Scenario.ManagedToUnmanagedIn, typeof(DoubleToBytesBigEndianMarshaller))]
|
[CustomMarshaller(typeof(double), MarshalMode.ManagedToUnmanagedIn, typeof(DoubleToBytesBigEndianMarshaller))]
|
||||||
public static unsafe class DoubleToBytesBigEndianMarshaller
|
public static unsafe class DoubleToBytesBigEndianMarshaller
|
||||||
{
|
{
|
||||||
public const int BufferSize = 8;
|
public const int BufferSize = 8;
|
||||||
|
@ -89,7 +89,7 @@ namespace SharedTypes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(double), Scenario.ManagedToUnmanagedIn, typeof(DoubleToLongMarshaller))]
|
[CustomMarshaller(typeof(double), MarshalMode.ManagedToUnmanagedIn, typeof(DoubleToLongMarshaller))]
|
||||||
public static class DoubleToLongMarshaller
|
public static class DoubleToLongMarshaller
|
||||||
{
|
{
|
||||||
public static long ConvertToUnmanaged(double managed)
|
public static long ConvertToUnmanaged(double managed)
|
||||||
|
@ -106,7 +106,7 @@ namespace SharedTypes
|
||||||
public bool b3;
|
public bool b3;
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(BoolStruct), Scenario.Default, typeof(BoolStructMarshaller))]
|
[CustomMarshaller(typeof(BoolStruct), MarshalMode.Default, typeof(BoolStructMarshaller))]
|
||||||
public static class BoolStructMarshaller
|
public static class BoolStructMarshaller
|
||||||
{
|
{
|
||||||
public struct BoolStructNative
|
public struct BoolStructNative
|
||||||
|
@ -145,7 +145,7 @@ namespace SharedTypes
|
||||||
public ref int GetPinnableReference() => ref i;
|
public ref int GetPinnableReference() => ref i;
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(IntWrapper), Scenario.Default, typeof(IntWrapperMarshaller))]
|
[CustomMarshaller(typeof(IntWrapper), MarshalMode.Default, typeof(IntWrapperMarshaller))]
|
||||||
public static unsafe class IntWrapperMarshaller
|
public static unsafe class IntWrapperMarshaller
|
||||||
{
|
{
|
||||||
public static int* ConvertToUnmanaged(IntWrapper managed)
|
public static int* ConvertToUnmanaged(IntWrapper managed)
|
||||||
|
@ -166,7 +166,7 @@ namespace SharedTypes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(IntWrapper), Scenario.Default, typeof(Marshaller))]
|
[CustomMarshaller(typeof(IntWrapper), MarshalMode.Default, typeof(Marshaller))]
|
||||||
public static unsafe class IntWrapperMarshallerStateful
|
public static unsafe class IntWrapperMarshallerStateful
|
||||||
{
|
{
|
||||||
public struct Marshaller
|
public struct Marshaller
|
||||||
|
@ -205,7 +205,7 @@ namespace SharedTypes
|
||||||
public int i;
|
public int i;
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(IntWrapperWithoutGetPinnableReference), Scenario.Default, typeof(IntWrapperWithoutGetPinnableReferenceMarshaller))]
|
[CustomMarshaller(typeof(IntWrapperWithoutGetPinnableReference), MarshalMode.Default, typeof(IntWrapperWithoutGetPinnableReferenceMarshaller))]
|
||||||
public static unsafe class IntWrapperWithoutGetPinnableReferenceMarshaller
|
public static unsafe class IntWrapperWithoutGetPinnableReferenceMarshaller
|
||||||
{
|
{
|
||||||
public static int* ConvertToUnmanaged(IntWrapperWithoutGetPinnableReference managed)
|
public static int* ConvertToUnmanaged(IntWrapperWithoutGetPinnableReference managed)
|
||||||
|
@ -228,7 +228,7 @@ namespace SharedTypes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(IntWrapperWithoutGetPinnableReference), Scenario.ManagedToUnmanagedIn, typeof(StatelessGetPinnableReference))]
|
[CustomMarshaller(typeof(IntWrapperWithoutGetPinnableReference), MarshalMode.ManagedToUnmanagedIn, typeof(StatelessGetPinnableReference))]
|
||||||
public static unsafe class IntWrapperWithoutGetPinnableReferenceStatefulMarshaller
|
public static unsafe class IntWrapperWithoutGetPinnableReferenceStatefulMarshaller
|
||||||
{
|
{
|
||||||
public struct StatelessGetPinnableReference
|
public struct StatelessGetPinnableReference
|
||||||
|
@ -242,7 +242,7 @@ namespace SharedTypes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(IntWrapperWithoutGetPinnableReference), Scenario.ManagedToUnmanagedIn, typeof(StatefulGetPinnableReference))]
|
[CustomMarshaller(typeof(IntWrapperWithoutGetPinnableReference), MarshalMode.ManagedToUnmanagedIn, typeof(StatefulGetPinnableReference))]
|
||||||
public static unsafe class IntWrapperWithoutGetPinnableReferenceStatefulNoAllocMarshaller
|
public static unsafe class IntWrapperWithoutGetPinnableReferenceStatefulNoAllocMarshaller
|
||||||
{
|
{
|
||||||
public struct StatefulGetPinnableReference
|
public struct StatefulGetPinnableReference
|
||||||
|
@ -281,7 +281,7 @@ namespace SharedTypes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(IntWrapperWithNotification), Scenario.Default, typeof(Marshaller))]
|
[CustomMarshaller(typeof(IntWrapperWithNotification), MarshalMode.Default, typeof(Marshaller))]
|
||||||
public static class IntWrapperWithNotificationMarshaller
|
public static class IntWrapperWithNotificationMarshaller
|
||||||
{
|
{
|
||||||
public struct Marshaller
|
public struct Marshaller
|
||||||
|
@ -296,11 +296,11 @@ namespace SharedTypes
|
||||||
|
|
||||||
public IntWrapperWithNotification ToManaged() => _managed;
|
public IntWrapperWithNotification ToManaged() => _managed;
|
||||||
|
|
||||||
public void NotifyInvokeSucceeded() => _managed.RaiseInvokeSucceeded();
|
public void OnInvoked() => _managed.RaiseInvokeSucceeded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(BoolStruct), Scenario.Default, typeof(Marshaller))]
|
[CustomMarshaller(typeof(BoolStruct), MarshalMode.Default, typeof(Marshaller))]
|
||||||
public static class BoolStructMarshallerStateful
|
public static class BoolStructMarshallerStateful
|
||||||
{
|
{
|
||||||
public struct BoolStructNative
|
public struct BoolStructNative
|
||||||
|
@ -339,8 +339,9 @@ namespace SharedTypes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(List<>), Scenario.Default, typeof(ListMarshaller<,>))]
|
[CustomMarshaller(typeof(List<>), MarshalMode.Default, typeof(ListMarshaller<,>))]
|
||||||
public unsafe static class ListMarshaller<T, [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
[ContiguousCollectionMarshaller]
|
||||||
|
public unsafe static class ListMarshaller<T, TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
public static byte* AllocateContainerForUnmanagedElements(List<T> managed, out int numElements)
|
public static byte* AllocateContainerForUnmanagedElements(List<T> managed, out int numElements)
|
||||||
=> AllocateContainerForUnmanagedElements(managed, Span<byte>.Empty, out numElements);
|
=> AllocateContainerForUnmanagedElements(managed, Span<byte>.Empty, out numElements);
|
||||||
|
@ -397,8 +398,9 @@ namespace SharedTypes
|
||||||
=> Marshal.FreeCoTaskMem((IntPtr)unmanaged);
|
=> Marshal.FreeCoTaskMem((IntPtr)unmanaged);
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(List<>), Scenario.Default, typeof(ListMarshallerWithPinning<,>))]
|
[CustomMarshaller(typeof(List<>), MarshalMode.Default, typeof(ListMarshallerWithPinning<,>))]
|
||||||
public unsafe static class ListMarshallerWithPinning<T, [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
[ContiguousCollectionMarshaller]
|
||||||
|
public unsafe static class ListMarshallerWithPinning<T, TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
public static byte* AllocateContainerForUnmanagedElements(List<T> managed, out int numElements)
|
public static byte* AllocateContainerForUnmanagedElements(List<T> managed, out int numElements)
|
||||||
=> AllocateContainerForUnmanagedElements(managed, Span<byte>.Empty, out numElements);
|
=> AllocateContainerForUnmanagedElements(managed, Span<byte>.Empty, out numElements);
|
||||||
|
@ -464,8 +466,9 @@ namespace SharedTypes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(CustomMarshallerAttribute.GenericPlaceholder[]), Scenario.Default, typeof(CustomArrayMarshaller<,>))]
|
[CustomMarshaller(typeof(CustomMarshallerAttribute.GenericPlaceholder[]), MarshalMode.Default, typeof(CustomArrayMarshaller<,>))]
|
||||||
public unsafe static class CustomArrayMarshaller<T, [ElementUnmanagedType] TUnmanagedElement> where TUnmanagedElement : unmanaged
|
[ContiguousCollectionMarshaller]
|
||||||
|
public unsafe static class CustomArrayMarshaller<T, TUnmanagedElement> where TUnmanagedElement : unmanaged
|
||||||
{
|
{
|
||||||
public static byte* AllocateContainerForUnmanagedElements(T[]? managed, out int numElements)
|
public static byte* AllocateContainerForUnmanagedElements(T[]? managed, out int numElements)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue