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

Add new proposed API to Ancillary.Interop #81063

Merged
merged 26 commits into from
Feb 17, 2023

Conversation

jtschuster
Copy link
Member

Adds the new APIs from Jeremy's proposal to Ancillary.Interop project and makes the minimum changes not break the build and tests of the VTable generator.

@ghost
Copy link

ghost commented Jan 24, 2023

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

Issue Details

Adds the new APIs from Jeremy's proposal to Ancillary.Interop project and makes the minimum changes not break the build and tests of the VTable generator.

Author: jtschuster
Assignees: jtschuster
Labels:

area-System.Runtime.InteropServices

Milestone: -

jtschuster and others added 3 commits January 23, 2023 20:01
…eGenerator.Tests/VTableGCHandlePair.cs

Co-authored-by: Aaron Robinson <arobins@microsoft.com>
- Add license banner to new files
- Change count to 0 for null VTables
- Move types to their own file and update comments
- Re-add dereference to 'this' pointer for vtable
@jtschuster jtschuster marked this pull request as draft January 31, 2023 00:35
jtschuster and others added 9 commits January 30, 2023 17:38
- Add license banner to new files
- Change count to 0 for null VTables
…eGenerator.Tests/VTableGCHandlePair.cs

Co-authored-by: Aaron Robinson <arobins@microsoft.com>
- Move types to their own file and update comments
- Re-add dereference to 'this' pointer for vtable
@jtschuster jtschuster marked this pull request as ready for review January 31, 2023 22:02
@jtschuster
Copy link
Member Author

ImplicitThisTests.cs generated code:

// <auto-generated/> ManagedToNativeStubs.g.cs
namespace ComInterfaceGenerator.Tests
{
    internal unsafe partial class NativeExportsNE
    {
        internal unsafe partial class ImplicitThis
        {
            internal unsafe partial interface INativeObject
            {
                internal unsafe partial interface Native
                {
                    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.ComInterfaceGenerator", "42.42.42.42")]
                    [System.Runtime.CompilerServices.SkipLocalsInitAttribute]
                    int INativeObject.GetData()
                    {
                        var(__this, __vtable_native) = ((System.Runtime.InteropServices.Marshalling.IUnmanagedVirtualMethodTableProvider)this).GetVirtualMethodTableInfoForKey(typeof(global::ComInterfaceGenerator.Tests.NativeExportsNE.ImplicitThis.INativeObject));
                        int __retVal;
                        {
                            __retVal = ((delegate* unmanaged<void*, int> )__vtable_native[0])(__this);
                        }

                        return __retVal;
                    }
                }
            }
        }
    }
}
namespace ComInterfaceGenerator.Tests
{
    internal unsafe partial class NativeExportsNE
    {
        internal unsafe partial class ImplicitThis
        {
            internal unsafe partial interface INativeObject
            {
                internal unsafe partial interface Native
                {
                    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.ComInterfaceGenerator", "42.42.42.42")]
                    [System.Runtime.CompilerServices.SkipLocalsInitAttribute]
                    void INativeObject.SetData(int x)
                    {
                        var(__this, __vtable_native) = ((System.Runtime.InteropServices.Marshalling.IUnmanagedVirtualMethodTableProvider)this).GetVirtualMethodTableInfoForKey(typeof(global::ComInterfaceGenerator.Tests.NativeExportsNE.ImplicitThis.INativeObject));
                        {
                            ((delegate* unmanaged<void*, int, void> )__vtable_native[1])(__this, x);
                        }
                    }
                }
            }
        }
    }
}

// <auto-generated/> NativeInterfaces.g.cs
namespace ComInterfaceGenerator.Tests
{
    internal unsafe partial class NativeExportsNE
    {
        internal unsafe partial class ImplicitThis
        {
            internal unsafe partial interface INativeObject
            {
                [System.Runtime.InteropServices.DynamicInterfaceCastableImplementationAttribute]
                internal partial interface Native : INativeObject
                {
                }
            }
        }
    }
}

// <auto-generated/> NativeToManagedStubs.g.cs
namespace ComInterfaceGenerator.Tests
{
    internal unsafe partial class NativeExportsNE
    {
        internal unsafe partial class ImplicitThis
        {
            internal unsafe partial interface INativeObject
            {
                internal unsafe partial interface Native
                {
                    [System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute]
                    internal static int ABI_GetData(void* __this_native)
                    {
                        global::ComInterfaceGenerator.Tests.NativeExportsNE.ImplicitThis.INativeObject @this;
                        int __retVal = default;
                        // Unmarshal - Convert native data to managed data.
                        @this = (global::ComInterfaceGenerator.Tests.NativeExportsNE.ImplicitThis.INativeObject)System.Runtime.InteropServices.Marshalling.UnmanagedObjectUnwrapper.GetObjectForUnmanagedWrapper<ComInterfaceGenerator.Tests.VTableGCHandlePair<ComInterfaceGenerator.Tests.NativeExportsNE.ImplicitThis.INativeObject>>(__this_native);
                        __retVal = @this.GetData();
                        return __retVal;
                    }
                }
            }
        }
    }
}
namespace ComInterfaceGenerator.Tests
{
    internal unsafe partial class NativeExportsNE
    {
        internal unsafe partial class ImplicitThis
        {
            internal unsafe partial interface INativeObject
            {
                internal unsafe partial interface Native
                {
                    [System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute]
                    internal static void ABI_SetData(void* __this_native, int x)
                    {
                        global::ComInterfaceGenerator.Tests.NativeExportsNE.ImplicitThis.INativeObject @this;
                        // Unmarshal - Convert native data to managed data.
                        @this = (global::ComInterfaceGenerator.Tests.NativeExportsNE.ImplicitThis.INativeObject)System.Runtime.InteropServices.Marshalling.UnmanagedObjectUnwrapper.GetObjectForUnmanagedWrapper<ComInterfaceGenerator.Tests.VTableGCHandlePair<ComInterfaceGenerator.Tests.NativeExportsNE.ImplicitThis.INativeObject>>(__this_native);
                        @this.SetData(x);
                    }
                }
            }
        }
    }
}


// <auto-generated/> PopulateVTable.g.cs
namespace ComInterfaceGenerator.Tests
{
    internal unsafe partial class NativeExportsNE
    {
        internal unsafe partial class ImplicitThis
        {
            internal unsafe partial interface INativeObject
            {
                internal unsafe partial interface Native
                {
                    internal static void PopulateUnmanagedVirtualMethodTable(void** vtable)
                    {
                        vtable[0] = (void*)(delegate* unmanaged<void*, int> )&ABI_GetData;
                        vtable[1] = (void*)(delegate* unmanaged<void*, int, void> )&ABI_SetData;
                    }
                }
            }
        }
    }
}

NoImplicitThis.cs generated code:

// <auto-generated/> NativeInterfaces.g.cs
namespace ComInterfaceGenerator.Tests
{
    internal unsafe partial class NativeExportsNE
    {
        internal unsafe partial class NoImplicitThis
        {
            internal unsafe partial interface IStaticMethodTable
            {
                [System.Runtime.InteropServices.DynamicInterfaceCastableImplementationAttribute]
                internal partial interface Native : IStaticMethodTable
                {
                }
            }
        }
    }
}


// <auto-generated/> ManagedToNativeStubs.g.cs
namespace ComInterfaceGenerator.Tests
{
    internal unsafe partial class NativeExportsNE
    {
        internal unsafe partial class NoImplicitThis
        {
            internal unsafe partial interface IStaticMethodTable
            {
                internal unsafe partial interface Native
                {
                    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.ComInterfaceGenerator", "42.42.42.42")]
                    [System.Runtime.CompilerServices.SkipLocalsInitAttribute]
                    int IStaticMethodTable.Add(int x, int y)
                    {
                        var(__this, __vtable_native) = ((System.Runtime.InteropServices.Marshalling.IUnmanagedVirtualMethodTableProvider)this).GetVirtualMethodTableInfoForKey(typeof(global::ComInterfaceGenerator.Tests.NativeExportsNE.NoImplicitThis.IStaticMethodTable));
                        int __retVal;
                        {
                            __retVal = ((delegate* unmanaged<int, int, int> )__vtable_native[0])(x, y);
                        }

                        return __retVal;
                    }
                }
            }
        }
    }
}
namespace ComInterfaceGenerator.Tests
{
    internal unsafe partial class NativeExportsNE
    {
        internal unsafe partial class NoImplicitThis
        {
            internal unsafe partial interface IStaticMethodTable
            {
                internal unsafe partial interface Native
                {
                    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.ComInterfaceGenerator", "42.42.42.42")]
                    [System.Runtime.CompilerServices.SkipLocalsInitAttribute]
                    int IStaticMethodTable.Multiply(int x, int y)
                    {
                        var(__this, __vtable_native) = ((System.Runtime.InteropServices.Marshalling.IUnmanagedVirtualMethodTableProvider)this).GetVirtualMethodTableInfoForKey(typeof(global::ComInterfaceGenerator.Tests.NativeExportsNE.NoImplicitThis.IStaticMethodTable));
                        int __retVal;
                        {
                            __retVal = ((delegate* unmanaged<int, int, int> )__vtable_native[1])(x, y);
                        }

                        return __retVal;
                    }
                }
            }
        }
    }
}

…erop.SourceGeneration/TypeSymbolExtensions.cs

Co-authored-by: Jeremy Koritzinsky <jkoritzinsky@gmail.com>
…enerator/Marshallers/NativeToManagedThisMarshallerFactory.cs

Co-authored-by: Jeremy Koritzinsky <jkoritzinsky@gmail.com>
Copy link
Member

@jkoritzinsky jkoritzinsky left a comment

Choose a reason for hiding this comment

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

Just one more nit.

After that's fixed and the files are moved from file-scoped namespaces back to traditional namespaces, this will be ready to merge!

@jkoritzinsky
Copy link
Member

Looks like there were some conflicts from the COM source generator skeleton PR. Can we resolve those and retrigger CI?

@jkoritzinsky
Copy link
Member

It looks like you need to build this locally to update the Xlf files. I know it's a pain, I wish we could cloud-automate it.

Copy link
Member

@elinor-fung elinor-fung left a comment

Choose a reason for hiding this comment

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

Just minor comments - nothing that I think is worth resetting CI for. Feel free to address in a future change.

@@ -207,6 +207,9 @@
<data name="InterfaceTypeNotSupportedMessage" xml:space="preserve">
<value>Using 'GeneratedComInterfaceAttribute' and 'InterfaceTypeAttribute' is not supported with 'ComInterfaceType' value '{0}'.</value>
</data>
<data name="InvalidAttributedMethodContainingTypeMissingUnmanagedObjectUnwrapperAttributeMessage" xml:space="preserve">
<value>Containing type of method with VirtualMethodIndexAttribute does not have a UnmanagedObjectUnwrapperAttribute. </value>
Copy link
Member

Choose a reason for hiding this comment

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

nit: single quote around type names

@@ -3,6 +3,8 @@

using System;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Syntax;
Copy link
Member

Choose a reason for hiding this comment

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

Do we need this?

public static bool IsOfType(this INamedTypeSymbol type, string typeName)
{
if (typeName.Contains('<') || typeName.Contains('+') || typeName.Contains('/'))
throw new ArgumentException($"Cannot handle type name in the format provided: {typeName}", nameof(typeName));
Copy link
Member

Choose a reason for hiding this comment

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

nit: newlines after the single-line blocks

@@ -45,6 +45,16 @@ public class Ids
isEnabledByDefault: true,
description: GetResourceString(nameof(SR.InvalidAttributedMethodDescription)));

public static readonly DiagnosticDescriptor InvalidAttributedMethodContainingTypeMissingUnmanagedObjectUnwrapperAttribute =
new DiagnosticDescriptor(
Ids.InvalidLibraryImportAttributeUsage,
Copy link
Member

Choose a reason for hiding this comment

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

(for later change) We should probably have a different ID for the diagnostics here.


namespace Microsoft.Interop
{
internal static class InlinedTypes
Copy link
Member

Choose a reason for hiding this comment

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

I assume this is just prep for later? I don't see it used yet.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, this is unused but may be needed later.

@jtschuster jtschuster merged commit 4dea84c into dotnet:main Feb 17, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Mar 20, 2023
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.

4 participants