Skip to content

ComInterfaceGenerator emits method attributed with [UnmanagedCallersOnly] and in out or ref parameters.  #82581

@jtschuster

Description

@jtschuster

ComInterfaceGenerator generates code that produces error CS8977: Cannot use 'ref', 'in', or 'out' in the signature of a method attributed with 'UnmanagedCallersOnly'.

User Code:

[assembly:DisableRuntimeMarshalling]

[global::System.Runtime.InteropServices.Marshalling.GeneratedComInterfaceAttribute]
partial interface INativeAPI : IUnmanagedInterfaceType
{
    
    void Method(out S value);
}
// Try using the generated native interface
sealed class NativeAPI : IUnmanagedVirtualMethodTableProvider, INativeAPI.Native
{
    public VirtualMethodTableInfo GetVirtualMethodTableInfoForKey(System.Type type) => throw null;
}
partial interface INativeAPI
{
        static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
}
[NativeMarshalling(typeof(Marshaller))]
public struct S
{
#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value
    public bool b;
#pragma warning restore CS0649
}

[CustomMarshaller(typeof(S), MarshalMode.ManagedToUnmanagedOut, typeof(Marshaller))]
[CustomMarshaller(typeof(S), MarshalMode.UnmanagedToManagedIn, typeof(Marshaller))]
public static class Marshaller
{
    public struct Native { }

    public static S ConvertToManaged(Native n) => default;
}

NativeToManagedStubs.g.cs

// <auto-generated/>
unsafe partial interface INativeAPI
{
    internal unsafe partial interface Native
    {
        // error CS8977: Cannot use 'ref', 'in', or 'out' in the signature of a method attributed with 'UnmanagedCallersOnly'.
        [System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute]
        internal static void ABI_Method(void* __this_native, out global::S value)
        {
            global::INativeAPI @this = default;
            try
            {
                // Unmarshal - Convert native data to managed data.
                @this = (global::INativeAPI)System.Runtime.InteropServices.Marshalling.UnmanagedObjectUnwrapper.GetObjectForUnmanagedWrapper<System.Runtime.InteropServices.Marshalling.ComWrappersUnwrapper>(__this_native);
                @this.Method(out value);
            }
            catch (System.Exception __exception)
            {
                System.Runtime.InteropServices.Marshalling.SwallowExceptionMarshaller.ConvertToUnmanaged(__exception);
            }
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions