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

Update string marshallers to V2 shape #71849

Merged
merged 8 commits into from
Jul 10, 2022

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);
}

@dotnet-issue-labeler
Copy link

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

src/coreclr/vm/clsload.cpp Outdated Show resolved Hide resolved
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