2

I'm going to migrate a .NET Framework 4.* application to .NET 6. Main application is compiled as 64bit and I need to use a 32bit (.NET 6) dll hosted as out-of-process in Windows system surrogate (dllhost) that interact with x86 third party driver.

I wrote a sample with a 32-bit server, implemented as a C# class in a class library project, hosted by Windows system surrogate. I need to handle events between main application and dllhost but in .NET 6 I have the following exception during event handler registration:

Cannot marshal 'parameter #1': .NET Core does not support marshalling delegates to the _Delegate interface provided by the .NET Framework COM Type Library. To marshal a delegate as an interface, marshal it as an IDispatch pointer.

It works fine if I compile both with .NET 4.*.

How can I define and handle events in .NET 6 implementation?

Class code:

namespace OutOfProcCOM;

[ComVisible(true)]
[Guid(Contract.Constants.ServerInterface)]  //F586D6F4-AF37-441E-80A6-3D33D977882D
public interface IServer
{
    double Test();

    event OnMyEventDelegate OnMyEvent;
}

[ComVisible(true)]
[Guid(Contract.Constants.ServerInterface)]  //F586D6F4-AF37-441E-80A6-3D33D977882D
public delegate void OnMyEventDelegate(string text);

[ComVisible(true)]
[Guid(Contract.Constants.ServerInterface)]
public interface IMyEvents
{
    [DispId(1)]
    void OnMyEvent(string text);
}

[ComVisible(true)]
[ComSourceInterfaces(typeof(IMyEvents))]
[Guid(Contract.Constants.ServerClass)]  //"AF080472-F173-4D9D-8BE7-435776617347"
public sealed class DllServer : IServer
{
    public event OnMyEventDelegate OnMyEvent;

    public double Test()
    {
        OnMyEvent?.Invoke("Hello");

        return 10;
    }
}

This is how I register it:

regsvr32.exe "DllServer.comhost.dll"

Registry entry

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Wow6432Node\AppID\{AF080472-F173-4D9D-8BE7-435776617347}]
"DllSurrogate"=""

[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{AF080472-F173-4D9D-8BE7-435776617347}]
"AppID"="{AF080472-F173-4D9D-8BE7-435776617347}"

And here is the client:

var type = Type.GetTypeFromProgID("OutOfProcCOM.DllServer");
var obj = (IServer)Activator.CreateInstance(type);
obj.OnMyEvent += (OnMyEventDelegate)((t) =>
{
    Console.WriteLine(t);
});
var x = obj.ComputePi();

Thanks!

ale91
  • 316
  • 3
  • 8
  • I think it is trying to tell you that you need to apply the [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] attribute to the IMyEvents interface declaration. Bit of a guess, using COM to marshal between .NET components is tricky business. – Hans Passant May 06 '22 at 17:24
  • @HansPassant thank you, but applying [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] doesn't working: same exception. I tried to setup events using "[MarshalAs(UnmanagedType.FunctionPtr)] ChangeDelegate d " and it's working. I think that .NET Core doesn't support events marshaling; not the cleanest solution but it's working (I have created a method to define all delegates used in the dll). – ale91 May 09 '22 at 06:32

0 Answers0