Skip to content

Using "Source generation for ComWrappers" documentation code crashes .NET 8 with a System.ExecutionEngineException #106978

Description

@smourier

Description

When using documentation at https://learn.microsoft.com/en-us/dotnet/standard/native-interop/comwrappers-source-generation (with AOT and disabled runtime marshalling), the code crashes with a Fatal error. Internal CLR error. (0x80131506) (System.ExecutionEngineException).

Reproduction Steps

Here's my .csproj:

<Project Sdk="Microsoft.NET.Sdk">
	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>net8.0</TargetFramework>
		<Nullable>enable</Nullable>
		<PublishAot>true</PublishAot>
		<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
	</PropertyGroup>
</Project>

Here's my Program.cs:

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;

[assembly: DisableRuntimeMarshalling]

namespace ConsoleAotAuthor
{
    internal partial class Program
    {
        static void Main()
        {
            var cw = new StrategyBasedComWrappers();
            var foo = new Foo();
            var unk = cw.GetOrCreateComInterfaceForObject(foo, CreateComInterfaceFlags.None);
            GivePointerToComInterface(unk);
        }

        [LibraryImport("Dll1.dll")]
        private static partial void GivePointerToComInterface(nint comObject);
    }

    [GeneratedComInterface, Guid("217104c3-ce28-4d13-a32e-ef65ee75edf1")]
    public partial interface IFoo
    {
        void Method(int i);
    }

    [GeneratedComClass]
    public partial class Foo : IFoo
    {
        public void Method(int i) => Console.WriteLine(".NET i:" + i);
    }
}

My dll1.cpp:

#include <windows.h>

BOOL __stdcall DllMain(HMODULE hModule, DWORD  dwReason, LPVOID lpReserved)
{
	return TRUE;
}

MIDL_INTERFACE("8c485499-003f-49c1-b8b6-a1ba8c53307c")
IFoo : public IUnknown
{
public:
	virtual void STDMETHODCALLTYPE Method(int i) = 0;
};

void __stdcall GivePointerToComInterface(IFoo* foo)
{
	foo->Method(12345678);
}

My dll1.def (to export the method):

LIBRARY
EXPORTS
	GivePointerToComInterface PRIVATE

Expected behavior

I believe it should just run without problem.

Actual behavior

The code crashes with a Fatal error. Internal CLR error. (0x80131506) (System.ExecutionEngineException). I'm not sure if it should work as in the documentation or if it shouldn't, but crashing is a bit violent.

Regression?

Seems like a regresssion if the documentation can be trusted but can it? I've remarked the doc code doesn't compile as is as it's not using today mandatory CreateComInterfaceFlags.

Known Workarounds

The code works if we do this instead of passing the native pointer directly:

var iid = typeof(IFoo).GUID;
Marshal.QueryInterface(unk, iid, out var ppv);
GivePointerToComInterface(ppv);
Marshal.Release(ppv);

That's why I'm unsure it's not the good way to have this work? I can understand I could have to QI the IUnknown interface if there are multiple vtable on my object, so maybe it's always expected?

Configuration

.NET SDK 8.0.400, Visual Studio 17.11.1

Other information

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    • Status
      No status

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions