Why isn't ICustomMarshaler being called for event delegate?

0

I'm struggling with ICustomMarshaler, and I can't find anyone else who is having this problem. The fact that I've been looking for an answer for days, and I'm finally posting here means that I'll probably find the answer ten minutes from now myself. :-\

I have a C# event being proxied to a COM event sink. I want to marshal an array of objects with two strings and an int using an ICustomMarshaler.

My problem is that I have everything defined, but my ICustomMarshaler isn't being used. I put breakpoints on GetInstance and MarshalManagedToNative, and they're never hit.

My ICustomMarshaler does get called when I go the other direction.

Is there a problem with using a custom marshaler with C# events/COM event sinks?

Here is the object I'm trying to serialize:

using System;
using System.Runtime.InteropServices;

namespace ComDll
{
    [StructLayout(LayoutKind.Sequential)]
    [Guid(ClassId), ComVisible(true)]
    public class ParamStruct
    {
        [MarshalAs(UnmanagedType.BStr)]
        public string Key;
        [MarshalAs(UnmanagedType.BStr)]
        public string Value;
        [MarshalAs(UnmanagedType.I4)]
        public int Number;

        internal const string ClassId = "8163B82F-E0AD-47BC-8F82-EFA324DCFB95";
    }
}

In the object, I tried leaving off the MarshalAs attributes, since they won't actually be used, and that results in 0x80028019 (old format or invalid type library). It wouldn't if my custom marshaler were being used.

Here is my ICustomMarshaler. Note: I'm leaving out the actual function contents since GetInstance or anything else isn't being called:

using System;
using System.Runtime.InteropServices;

namespace ComDll
{
    public class ParamStructArrayMarshaler : ICustomMarshaler
    {
        private static ICustomMarshaler _marshaler;
        public static ICustomMarshaler GetInstance(string cookie)
        {
            if(null == _marshaler)
            {
                _marshaler = new ParamStructArrayMarshaler();
            }
            return _marshaler;
        }

        public object MarshalNativeToManaged(IntPtr pNativeData)
        {
            // <Snip>
        }

        public IntPtr MarshalManagedToNative(object ManagedObj)
        {
            // <Snip>
        }

        public void CleanUpManagedData(object ManagedObj)
        {
            // <Snip>
        }

        public void CleanUpNativeData(IntPtr pNativeData)
        {
            // <Snip>
        }

        public int GetNativeDataSize()
        {
            // <Snip>
        }
    }
}

Here's the function definition in my interface:

[DispId(2)]
void ParamsWereSent(
    [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ParamStructArrayMarshaler)), In]
    ParamStruct[] paramArray,
    [In] int count);

Here's the delegate I use and the event that exposes it:

[ComVisible(false)]
public delegate void ParamsWereSentHandler(
    [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ParamStructArrayMarshaler)), In]
    ParamStruct[] paramArray,
    [In] int count);
public event ParamsWereSentHandler ParamsWereSent;

The fact that I can't find anyone else who is having trouble actually getting their ICustomMarshaler to be called means that I'm just missing something silly.

c#
c++
com
interop
com-interop
asked on Stack Overflow Mar 25, 2019 by Jamie • edited Mar 26, 2019 by Jamie

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0