Почему ICustomMarshaler не вызывается для делегата события? - PullRequest
0 голосов
/ 25 марта 2019

Я борюсь с ICustomMarshaler, и я не могу найти кого-то еще, кто имеет эту проблему. Тот факт, что я искал ответ в течение нескольких дней и наконец публикую здесь сообщение, означает, что я, вероятно, сам найду ответ через десять минут. : - \

У меня есть событие C #, передаваемое в приемник событий COM. Я хочу упорядочить массив объектов с двумя строками и int, используя ICustomMarshaler.

Моя проблема в том, что у меня все определено, но мой ICustomMarshaler не используется. Я ставлю точки останова на GetInstance и MarshalManagedToNative, и они никогда не срабатывают.

Мой ICustomMarshaler вызывает , когда я иду в другом направлении.

Есть ли проблема с использованием пользовательского маршалера с событиями C # / приемниками событий COM?

Вот объект, который я пытаюсь сериализовать:

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";
    }
}

В объекте я попытался опустить атрибуты MarshalAs, поскольку они фактически не будут использоваться, и в результате получится 0x80028019 (старый формат или недопустимая библиотека типов). Не было бы, если бы использовался мой собственный маршалер.

Вот мой ICustomMarshaler. Примечание: я опускаю фактическое содержимое функции, так как GetInstance или что-то еще не вызывается:

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>
        }
    }
}

Вот определение функции в моем интерфейсе:

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

Вот делегат, которого я использую, и событие, которое его выставляет:

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

Тот факт, что я не могу найти кого-то, кто испытывает затруднения при фактическом вызове их ICustomMarshaler, означает, что я просто упускаю что-то глупое.

...