Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic support for stateless linear collection marshalling #71473

Merged
merged 3 commits into from
Jul 1, 2022

Conversation

elinor-fung
Copy link
Member

This plumbs through the element information we need for linear collection marshallers and adds basic stateless support. Only blittable elements are handled in this change.

Not handled:

  • caller-allocated buffer
  • guaranteed unmarshal
  • pinnable reference
  • non-blittable elements
Generated example
[LibraryImport("lib")]
[return: MarshalUsing(typeof(CustomArrayMarshaller<,>), CountElementName = "numValues")]
public static partial int[] Method(
    [MarshalUsing(typeof(CustomArrayMarshaller<,>))] int[] values,
    out int numValues);

public static partial int[] Method(int[] values, out int numValues)
{
    System.Runtime.CompilerServices.Unsafe.SkipInit(out numValues);
    byte* __values_native;
    int[] __retVal;
    byte* __retVal_native;
    // Setup - Perform required setup.
    int __retVal_native__numElements;
    int __values_native__numElements;
    // Marshal - Convert managed data to native data.
    __values_native = global::SharedTypes.CustomArrayMarshaller<int, int>.AllocateContainerForUnmanagedElements(values, out __values_native__numElements);
    global::SharedTypes.CustomArrayMarshaller<int, int>.GetManagedValuesSource(values).CopyTo(global::SharedTypes.CustomArrayMarshaller<int, int>.GetUnmanagedValuesDestination(__values_native, __values_native__numElements));
    // Pin - Pin data in preparation for calling the P/Invoke.
    fixed (int* __numValues_native = &numValues)
    {
        __retVal_native = __PInvoke(__values_native, __numValues_native);
    }

    // Unmarshal - Convert native data to managed data.
    __retVal_native__numElements = checked((int)(numValues));
    __retVal = global::SharedTypes.CustomArrayMarshaller<int, int>.AllocateContainerForManagedElements(__retVal_native, __retVal_native__numElements);
    global::SharedTypes.CustomArrayMarshaller<int, int>.GetUnmanagedValuesSource(__retVal_native, __retVal_native__numElements).CopyTo(global::SharedTypes.CustomArrayMarshaller<int, int>.GetManagedValuesDestination(__retVal));
    return __retVal;
    // Local P/Invoke
    [System.Runtime.InteropServices.DllImportAttribute("Microsoft.Interop.Tests.NativeExportsNE", EntryPoint = "sum_int_array", ExactSpelling = true)]
    static extern unsafe byte* __PInvoke(byte* values, int* numValues);
}

[LibraryImport("lib")]
[return: MarshalUsing(typeof(ListMarshaller<,>), CountElementName = "numValues")]
public static partial List<int> Method(
    [MarshalUsing(typeof(ListMarshaller<,>))] List<int> values,
    out int numValues);

public static partial global::System.Collections.Generic.List<int> Method(global::System.Collections.Generic.List<int> values, out int numValues)
{
    System.Runtime.CompilerServices.Unsafe.SkipInit(out numValues);
    byte* __values_native;
    global::System.Collections.Generic.List<int> __retVal;
    byte* __retVal_native;
    // Setup - Perform required setup.
    int __retVal_native__numElements;
    int __values_native__numElements;
    // Marshal - Convert managed data to native data.
    __values_native = global::SharedTypes.ListMarshaller<int, int>.AllocateContainerForUnmanagedElements(values, out __values_native__numElements);
    global::SharedTypes.ListMarshaller<int, int>.GetManagedValuesSource(values).CopyTo(global::SharedTypes.ListMarshaller<int, int>.GetUnmanagedValuesDestination(__values_native, __values_native__numElements));
    // Pin - Pin data in preparation for calling the P/Invoke.
    fixed (int* __numValues_native = &numValues)
    {
        __retVal_native = __PInvoke(__values_native, __numValues_native);
    }

    // Unmarshal - Convert native data to managed data.
    __retVal_native__numElements = checked((int)(numValues));
    __retVal = global::SharedTypes.ListMarshaller<int, int>.AllocateContainerForManagedElements(__retVal_native, __retVal_native__numElements);
    global::SharedTypes.ListMarshaller<int, int>.GetUnmanagedValuesSource(__retVal_native, __retVal_native__numElements).CopyTo(global::SharedTypes.ListMarshaller<int, int>.GetManagedValuesDestination(__retVal));
    return __retVal;
    // Local P/Invoke
    [System.Runtime.InteropServices.DllImportAttribute("Microsoft.Interop.Tests.NativeExportsNE", EntryPoint = "sum_int_array", ExactSpelling = true)]
    static extern unsafe byte* __PInvoke(byte* values, int* numValues);
}

@elinor-fung elinor-fung added area-System.Runtime.InteropServices source-generator Indicates an issue with a source generator feature labels Jun 30, 2022
@elinor-fung elinor-fung added this to the 7.0.0 milestone Jun 30, 2022
@ghost ghost assigned elinor-fung Jun 30, 2022
@ghost
Copy link

ghost commented Jun 30, 2022

Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.

Issue Details

This plumbs through the element information we need for linear collection marshallers and adds basic stateless support. Only blittable elements are handled in this change.

Not handled:

  • caller-allocated buffer
  • guaranteed unmarshal
  • pinnable reference
  • non-blittable elements
Generated example
[LibraryImport("lib")]
[return: MarshalUsing(typeof(CustomArrayMarshaller<,>), CountElementName = "numValues")]
public static partial int[] Method(
    [MarshalUsing(typeof(CustomArrayMarshaller<,>))] int[] values,
    out int numValues);

public static partial int[] Method(int[] values, out int numValues)
{
    System.Runtime.CompilerServices.Unsafe.SkipInit(out numValues);
    byte* __values_native;
    int[] __retVal;
    byte* __retVal_native;
    // Setup - Perform required setup.
    int __retVal_native__numElements;
    int __values_native__numElements;
    // Marshal - Convert managed data to native data.
    __values_native = global::SharedTypes.CustomArrayMarshaller<int, int>.AllocateContainerForUnmanagedElements(values, out __values_native__numElements);
    global::SharedTypes.CustomArrayMarshaller<int, int>.GetManagedValuesSource(values).CopyTo(global::SharedTypes.CustomArrayMarshaller<int, int>.GetUnmanagedValuesDestination(__values_native, __values_native__numElements));
    // Pin - Pin data in preparation for calling the P/Invoke.
    fixed (int* __numValues_native = &numValues)
    {
        __retVal_native = __PInvoke(__values_native, __numValues_native);
    }

    // Unmarshal - Convert native data to managed data.
    __retVal_native__numElements = checked((int)(numValues));
    __retVal = global::SharedTypes.CustomArrayMarshaller<int, int>.AllocateContainerForManagedElements(__retVal_native, __retVal_native__numElements);
    global::SharedTypes.CustomArrayMarshaller<int, int>.GetUnmanagedValuesSource(__retVal_native, __retVal_native__numElements).CopyTo(global::SharedTypes.CustomArrayMarshaller<int, int>.GetManagedValuesDestination(__retVal));
    return __retVal;
    // Local P/Invoke
    [System.Runtime.InteropServices.DllImportAttribute("Microsoft.Interop.Tests.NativeExportsNE", EntryPoint = "sum_int_array", ExactSpelling = true)]
    static extern unsafe byte* __PInvoke(byte* values, int* numValues);
}

[LibraryImport("lib")]
[return: MarshalUsing(typeof(ListMarshaller<,>), CountElementName = "numValues")]
public static partial List<int> Method(
    [MarshalUsing(typeof(ListMarshaller<,>))] List<int> values,
    out int numValues);

public static partial global::System.Collections.Generic.List<int> Method(global::System.Collections.Generic.List<int> values, out int numValues)
{
    System.Runtime.CompilerServices.Unsafe.SkipInit(out numValues);
    byte* __values_native;
    global::System.Collections.Generic.List<int> __retVal;
    byte* __retVal_native;
    // Setup - Perform required setup.
    int __retVal_native__numElements;
    int __values_native__numElements;
    // Marshal - Convert managed data to native data.
    __values_native = global::SharedTypes.ListMarshaller<int, int>.AllocateContainerForUnmanagedElements(values, out __values_native__numElements);
    global::SharedTypes.ListMarshaller<int, int>.GetManagedValuesSource(values).CopyTo(global::SharedTypes.ListMarshaller<int, int>.GetUnmanagedValuesDestination(__values_native, __values_native__numElements));
    // Pin - Pin data in preparation for calling the P/Invoke.
    fixed (int* __numValues_native = &numValues)
    {
        __retVal_native = __PInvoke(__values_native, __numValues_native);
    }

    // Unmarshal - Convert native data to managed data.
    __retVal_native__numElements = checked((int)(numValues));
    __retVal = global::SharedTypes.ListMarshaller<int, int>.AllocateContainerForManagedElements(__retVal_native, __retVal_native__numElements);
    global::SharedTypes.ListMarshaller<int, int>.GetUnmanagedValuesSource(__retVal_native, __retVal_native__numElements).CopyTo(global::SharedTypes.ListMarshaller<int, int>.GetManagedValuesDestination(__retVal));
    return __retVal;
    // Local P/Invoke
    [System.Runtime.InteropServices.DllImportAttribute("Microsoft.Interop.Tests.NativeExportsNE", EntryPoint = "sum_int_array", ExactSpelling = true)]
    static extern unsafe byte* __PInvoke(byte* values, int* numValues);
}
Author: elinor-fung
Assignees: -
Labels:

area-System.Runtime.InteropServices, source-generator

Milestone: 7.0.0

Not handled:
- caller-allocated buffer
- guaranteed unmarshal
- pinnable reference
- non-blittable element marshalling
- element scenarios on custom marshallers
@elinor-fung elinor-fung force-pushed the basicStatelessCollection branch from c731b9a to d1f8d32 Compare June 30, 2022 16:04
@elinor-fung elinor-fung merged commit 19811c2 into dotnet:main Jul 1, 2022
@elinor-fung elinor-fung deleted the basicStatelessCollection branch July 1, 2022 19:34
@ghost ghost locked as resolved and limited conversation to collaborators Aug 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Runtime.InteropServices source-generator Indicates an issue with a source generator feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants