Skip to content

Conversation

@AaronRobinsonMSFT
Copy link
Member

@AaronRobinsonMSFT AaronRobinsonMSFT commented Jul 8, 2022

This updates the marshallers and the built-in system and NativeAOT's use of them.

/cc @elinor-fung @jkoritzinsky @jkotas

Generated code examples

UTF-16

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "42.42.42.42")]
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
public static partial string Strings(string a1, in string a2, ref string a3, out string a4)
{
    System.Runtime.CompilerServices.Unsafe.SkipInit(out a4);
    ushort* __a2_native = default;
    ushort* __a3_native = default;
    ushort* __a4_native = default;
    string __retVal;
    ushort* __retVal_native = default;
    try
    {
        // Marshal - Convert managed data to native data.
        __a2_native = global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.ConvertToUnmanaged(a2);
        __a3_native = global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.ConvertToUnmanaged(a3);
        // Pin - Pin data in preparation for calling the P/Invoke.
        fixed (void* __a1_native = &global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.GetPinnableReference(a1))
        {
            __retVal_native = __PInvoke((ushort*)__a1_native, &__a2_native, &__a3_native, &__a4_native);
        }

        // Unmarshal - Convert native data to managed data.
        __retVal = global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.ConvertToManaged(__retVal_native);
        a4 = global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.ConvertToManaged(__a4_native);
        a3 = global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.ConvertToManaged(__a3_native);
    }
    finally
    {
        // Cleanup - Perform required cleanup.
        global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.Free(__retVal_native);
        global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.Free(__a2_native);
        global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.Free(__a3_native);
        global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.Free(__a4_native);
    }

    return __retVal;
    // Local P/Invoke
    [System.Runtime.InteropServices.DllImportAttribute("Microsoft.Interop.Tests.NativeExportsNE", EntryPoint = "Strings", ExactSpelling = true)]
    static extern unsafe ushort* __PInvoke(ushort* a1, ushort** a2, ushort** a3, ushort** a4);
}

UTF-8

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "42.42.42.42")]
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
public static partial string Strings(string a1, in string a2, ref string a3, out string a4)
{
    System.Runtime.CompilerServices.Unsafe.SkipInit(out a4);
    byte* __a1_native = default;
    byte* __a2_native = default;
    byte* __a3_native = default;
    byte* __a4_native = default;
    string __retVal;
    byte* __retVal_native = default;
    // Setup - Perform required setup.
    global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn __a1_native__marshaller = new();
    global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn __a2_native__marshaller = new();
    try
    {
        // Marshal - Convert managed data to native data.
        byte* __a1_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize];
        __a1_native__marshaller.FromManaged(a1, new System.Span<byte>(__a1_native__stackptr, global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize));
        byte* __a2_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize];
        __a2_native__marshaller.FromManaged(a2, new System.Span<byte>(__a2_native__stackptr, global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize));
        __a3_native = global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ConvertToUnmanaged(a3);
        {
            // PinnedMarshal - Convert managed data to native data that requires the managed data to be pinned.
            __a1_native = __a1_native__marshaller.ToUnmanaged();
            __a2_native = __a2_native__marshaller.ToUnmanaged();
            __retVal_native = __PInvoke(__a1_native, &__a2_native, &__a3_native, &__a4_native);
        }

        // Unmarshal - Convert native data to managed data.
        __retVal = global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ConvertToManaged(__retVal_native);
        a4 = global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ConvertToManaged(__a4_native);
        a3 = global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ConvertToManaged(__a3_native);
    }
    finally
    {
        // Cleanup - Perform required cleanup.
        global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.Free(__retVal_native);
        __a1_native__marshaller.Free();
        __a2_native__marshaller.Free();
        global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.Free(__a3_native);
        global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.Free(__a4_native);
    }

    return __retVal;
    // Local P/Invoke
    [System.Runtime.InteropServices.DllImportAttribute("Microsoft.Interop.Tests.NativeExportsNE", EntryPoint = "Strings", ExactSpelling = true)]
    static extern unsafe byte* __PInvoke(byte* a1, byte** a2, byte** a3, byte** a4);
}

ANSI

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "42.42.42.42")]
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
public static partial string Strings(string a1, in string a2, ref string a3, out string a4)
{
    System.Runtime.CompilerServices.Unsafe.SkipInit(out a4);
    byte* __a1_native = default;
    byte* __a2_native = default;
    byte* __a3_native = default;
    byte* __a4_native = default;
    string __retVal;
    byte* __retVal_native = default;
    // Setup - Perform required setup.
    global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ManagedToUnmanagedIn __a1_native__marshaller = new();
    global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ManagedToUnmanagedIn __a2_native__marshaller = new();
    try
    {
        // Marshal - Convert managed data to native data.
        byte* __a1_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ManagedToUnmanagedIn.BufferSize];
        __a1_native__marshaller.FromManaged(a1, new System.Span<byte>(__a1_native__stackptr, global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ManagedToUnmanagedIn.BufferSize));
        byte* __a2_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ManagedToUnmanagedIn.BufferSize];
        __a2_native__marshaller.FromManaged(a2, new System.Span<byte>(__a2_native__stackptr, global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ManagedToUnmanagedIn.BufferSize));
        __a3_native = global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ConvertToUnmanaged(a3);
        {
            // PinnedMarshal - Convert managed data to native data that requires the managed data to be pinned.
            __a1_native = __a1_native__marshaller.ToUnmanaged();
            __a2_native = __a2_native__marshaller.ToUnmanaged();
            __retVal_native = __PInvoke(__a1_native, &__a2_native, &__a3_native, &__a4_native);
        }

        // Unmarshal - Convert native data to managed data.
        __retVal = global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ConvertToManaged(__retVal_native);
        a4 = global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ConvertToManaged(__a4_native);
        a3 = global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ConvertToManaged(__a3_native);
    }
    finally
    {
        // Cleanup - Perform required cleanup.
        global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.Free(__retVal_native);
        __a1_native__marshaller.Free();
        __a2_native__marshaller.Free();
        global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.Free(__a3_native);
        global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.Free(__a4_native);
    }

    return __retVal;
    // Local P/Invoke
    [System.Runtime.InteropServices.DllImportAttribute("Microsoft.Interop.Tests.NativeExportsNE", EntryPoint = "Strings", ExactSpelling = true)]
    static extern unsafe byte* __PInvoke(byte* a1, byte** a2, byte** a3, byte** a4);
}

BSTR

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "42.42.42.42")]
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
public static partial string Strings(string a1, in string a2, ref string a3, out string a4)
{
    System.Runtime.CompilerServices.Unsafe.SkipInit(out a4);
    ushort* __a1_native = default;
    ushort* __a2_native = default;
    ushort* __a3_native = default;
    ushort* __a4_native = default;
    string __retVal;
    ushort* __retVal_native = default;
    // Setup - Perform required setup.
    global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.ManagedToUnmanagedIn __a1_native__marshaller = new();
    global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.ManagedToUnmanagedIn __a2_native__marshaller = new();
    try
    {
        // Marshal - Convert managed data to native data.
        byte* __a1_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.ManagedToUnmanagedIn.BufferSize];
        __a1_native__marshaller.FromManaged(a1, new System.Span<byte>(__a1_native__stackptr, global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.ManagedToUnmanagedIn.BufferSize));
        byte* __a2_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.ManagedToUnmanagedIn.BufferSize];
        __a2_native__marshaller.FromManaged(a2, new System.Span<byte>(__a2_native__stackptr, global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.ManagedToUnmanagedIn.BufferSize));
        __a3_native = global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.ConvertToUnmanaged(a3);
        {
            // PinnedMarshal - Convert managed data to native data that requires the managed data to be pinned.
            __a1_native = __a1_native__marshaller.ToUnmanaged();
            __a2_native = __a2_native__marshaller.ToUnmanaged();
            __retVal_native = __PInvoke(__a1_native, &__a2_native, &__a3_native, &__a4_native);
        }

        // Unmarshal - Convert native data to managed data.
        __retVal = global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.ConvertToManaged(__retVal_native);
        a4 = global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.ConvertToManaged(__a4_native);
        a3 = global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.ConvertToManaged(__a3_native);
    }
    finally
    {
        // Cleanup - Perform required cleanup.
        global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.Free(__retVal_native);
        __a1_native__marshaller.Free();
        __a2_native__marshaller.Free();
        global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.Free(__a3_native);
        global::System.Runtime.InteropServices.Marshalling.BStrStringMarshaller.Free(__a4_native);
    }

    return __retVal;
    // Local P/Invoke
    [System.Runtime.InteropServices.DllImportAttribute("Microsoft.Interop.Tests.NativeExportsNE", EntryPoint = "Strings", ExactSpelling = true)]
    static extern unsafe ushort* __PInvoke(ushort* a1, ushort** a2, ushort** a3, ushort** a4);
}

@ghost
Copy link

ghost commented Jul 8, 2022

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@ghost
Copy link

ghost commented Jul 8, 2022

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

Issue Details

This updates the marshallers and the built-in system and NativeAOT's use of them.

Generated code examples

UTF-16

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "42.42.42.42")]
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
public static partial string Strings(string a1, in string a2, ref string a3, out string a4)
{
    System.Runtime.CompilerServices.Unsafe.SkipInit(out a4);
    ushort* __a2_native = default;
    ushort* __a3_native = default;
    ushort* __a4_native = default;
    string __retVal;
    ushort* __retVal_native = default;
    try
    {
        // Marshal - Convert managed data to native data.
        __a2_native = global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.ConvertToUnmanaged(a2);
        __a3_native = global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.ConvertToUnmanaged(a3);
        // Pin - Pin data in preparation for calling the P/Invoke.
        fixed (void* __a1_native = &global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.GetPinnableReference(a1))
        {
            __retVal_native = __PInvoke((ushort*)__a1_native, &__a2_native, &__a3_native, &__a4_native);
        }

        // Unmarshal - Convert native data to managed data.
        __retVal = global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.ConvertToManaged(__retVal_native);
        a4 = global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.ConvertToManaged(__a4_native);
        a3 = global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.ConvertToManaged(__a3_native);
    }
    finally
    {
        // Cleanup - Perform required cleanup.
        global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.Free(__retVal_native);
        global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.Free(__a2_native);
        global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.Free(__a3_native);
        global::System.Runtime.InteropServices.Marshalling.Utf16StringMarshaller.Free(__a4_native);
    }

    return __retVal;
    // Local P/Invoke
    [System.Runtime.InteropServices.DllImportAttribute("Microsoft.Interop.Tests.NativeExportsNE", EntryPoint = "Strings", ExactSpelling = true)]
    static extern unsafe ushort* __PInvoke(ushort* a1, ushort** a2, ushort** a3, ushort** a4);
}

UTF-8

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "42.42.42.42")]
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
public static partial string Strings(string a1, in string a2, ref string a3, out string a4)
{
    System.Runtime.CompilerServices.Unsafe.SkipInit(out a4);
    byte* __a1_native = default;
    byte* __a2_native = default;
    byte* __a3_native = default;
    byte* __a4_native = default;
    string __retVal;
    byte* __retVal_native = default;
    // Setup - Perform required setup.
    global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn __a1_native__marshaller = new();
    global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn __a2_native__marshaller = new();
    try
    {
        // Marshal - Convert managed data to native data.
        byte* __a1_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize];
        __a1_native__marshaller.FromManaged(a1, new System.Span<byte>(__a1_native__stackptr, global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize));
        byte* __a2_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize];
        __a2_native__marshaller.FromManaged(a2, new System.Span<byte>(__a2_native__stackptr, global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize));
        __a3_native = global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ConvertToUnmanaged(a3);
        {
            // PinnedMarshal - Convert managed data to native data that requires the managed data to be pinned.
            __a1_native = __a1_native__marshaller.ToUnmanaged();
            __a2_native = __a2_native__marshaller.ToUnmanaged();
            __retVal_native = __PInvoke(__a1_native, &__a2_native, &__a3_native, &__a4_native);
        }

        // Unmarshal - Convert native data to managed data.
        __retVal = global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ConvertToManaged(__retVal_native);
        a4 = global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ConvertToManaged(__a4_native);
        a3 = global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ConvertToManaged(__a3_native);
    }
    finally
    {
        // Cleanup - Perform required cleanup.
        global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.Free(__retVal_native);
        __a1_native__marshaller.Free();
        __a2_native__marshaller.Free();
        global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.Free(__a3_native);
        global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.Free(__a4_native);
    }

    return __retVal;
    // Local P/Invoke
    [System.Runtime.InteropServices.DllImportAttribute("Microsoft.Interop.Tests.NativeExportsNE", EntryPoint = "Strings", ExactSpelling = true)]
    static extern unsafe byte* __PInvoke(byte* a1, byte** a2, byte** a3, byte** a4);
}

ANSI

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "42.42.42.42")]
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
public static partial string Strings(string a1, in string a2, ref string a3, out string a4)
{
    System.Runtime.CompilerServices.Unsafe.SkipInit(out a4);
    byte* __a1_native = default;
    byte* __a2_native = default;
    byte* __a3_native = default;
    byte* __a4_native = default;
    string __retVal;
    byte* __retVal_native = default;
    // Setup - Perform required setup.
    global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ManagedToUnmanagedIn __a1_native__marshaller = new();
    global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ManagedToUnmanagedIn __a2_native__marshaller = new();
    try
    {
        // Marshal - Convert managed data to native data.
        byte* __a1_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ManagedToUnmanagedIn.BufferSize];
        __a1_native__marshaller.FromManaged(a1, new System.Span<byte>(__a1_native__stackptr, global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ManagedToUnmanagedIn.BufferSize));
        byte* __a2_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ManagedToUnmanagedIn.BufferSize];
        __a2_native__marshaller.FromManaged(a2, new System.Span<byte>(__a2_native__stackptr, global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ManagedToUnmanagedIn.BufferSize));
        __a3_native = global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ConvertToUnmanaged(a3);
        {
            // PinnedMarshal - Convert managed data to native data that requires the managed data to be pinned.
            __a1_native = __a1_native__marshaller.ToUnmanaged();
            __a2_native = __a2_native__marshaller.ToUnmanaged();
            __retVal_native = __PInvoke(__a1_native, &__a2_native, &__a3_native, &__a4_native);
        }

        // Unmarshal - Convert native data to managed data.
        __retVal = global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ConvertToManaged(__retVal_native);
        a4 = global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ConvertToManaged(__a4_native);
        a3 = global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.ConvertToManaged(__a3_native);
    }
    finally
    {
        // Cleanup - Perform required cleanup.
        global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.Free(__retVal_native);
        __a1_native__marshaller.Free();
        __a2_native__marshaller.Free();
        global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.Free(__a3_native);
        global::System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller.Free(__a4_native);
    }

    return __retVal;
    // Local P/Invoke
    [System.Runtime.InteropServices.DllImportAttribute("Microsoft.Interop.Tests.NativeExportsNE", EntryPoint = "Strings", ExactSpelling = true)]
    static extern unsafe byte* __PInvoke(byte* a1, byte** a2, byte** a3, byte** a4);
}

BSTR

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "42.42.42.42")]
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
public static partial string Strings(string a1, in string a2, ref string a3, out string a4)
{
    System.Runtime.CompilerServices.Unsafe.SkipInit(out a4);
    ushort* __a1_native = default;
    ushort* __a2_native = default;
    ushort* __a3_native = default;
    ushort* __a4_native = default;
    string __retVal;
    ushort* __retVal_native = default;
    // Setup - Perform required setup.
    global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.ManagedToUnmanagedIn __a1_native__marshaller = new();
    global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.ManagedToUnmanagedIn __a2_native__marshaller = new();
    try
    {
        // Marshal - Convert managed data to native data.
        byte* __a1_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.ManagedToUnmanagedIn.BufferSize];
        __a1_native__marshaller.FromManaged(a1, new System.Span<byte>(__a1_native__stackptr, global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.ManagedToUnmanagedIn.BufferSize));
        byte* __a2_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.ManagedToUnmanagedIn.BufferSize];
        __a2_native__marshaller.FromManaged(a2, new System.Span<byte>(__a2_native__stackptr, global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.ManagedToUnmanagedIn.BufferSize));
        __a3_native = global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.ConvertToUnmanaged(a3);
        {
            // PinnedMarshal - Convert managed data to native data that requires the managed data to be pinned.
            __a1_native = __a1_native__marshaller.ToUnmanaged();
            __a2_native = __a2_native__marshaller.ToUnmanaged();
            __retVal_native = __PInvoke(__a1_native, &__a2_native, &__a3_native, &__a4_native);
        }

        // Unmarshal - Convert native data to managed data.
        __retVal = global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.ConvertToManaged(__retVal_native);
        a4 = global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.ConvertToManaged(__a4_native);
        a3 = global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.ConvertToManaged(__a3_native);
    }
    finally
    {
        // Cleanup - Perform required cleanup.
        global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.Free(__retVal_native);
        __a1_native__marshaller.Free();
        __a2_native__marshaller.Free();
        global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.Free(__a3_native);
        global::System.Runtime.InteropServices.Marshalling.BstrStringMarshaller.Free(__a4_native);
    }

    return __retVal;
    // Local P/Invoke
    [System.Runtime.InteropServices.DllImportAttribute("Microsoft.Interop.Tests.NativeExportsNE", EntryPoint = "Strings", ExactSpelling = true)]
    static extern unsafe ushort* __PInvoke(ushort* a1, ushort** a2, ushort** a3, ushort** a4);
}
Author: AaronRobinsonMSFT
Assignees: -
Labels:

area-System.Runtime.InteropServices

Milestone: 7.0.0

Avoid initialization of marshaller when not used.
Remove unneccessary unmanaged->managed APIs for In marshallers.
  that can be used to load nested classes.
Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you!

@jkotas jkotas merged commit 1af8727 into dotnet:main Jul 10, 2022
@AaronRobinsonMSFT AaronRobinsonMSFT deleted the update_strings branch July 10, 2022 02:28
@ghost ghost locked as resolved and limited conversation to collaborators Aug 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants