Как создать инстанс делегата, с дополнительным параметром (идентификатором)

Тема в разделе ".NET", создана пользователем EugenOS, 19 июн 2016.

Метки:
  1. EugenOS

    EugenOS Active Member

    Регистрация:
    22 июл 2007
    Сообщения:
    27
    Симпатии:
    0
    Доброго времени суток форумчанам. Вопрос к знатокам .NET

    В общем суть проблемы.
    Имею старенький девайс (на столько, что производитель уже не хочет его поддерживать.) но вполне работающий, и привычный. У него есть возможность работать с несколькими каналами, но в старых версиях библиотеки, callback функция назначалась на канал, но при этом не имела параметра идентификации "с какого канала получено событие". Т.е. предполагалось на каждый канал вешать свой отдельный обработчик. На C++Builder 6 я решал это просто, сделал класс обертку и добавлял канал в событие, которое уже имело такой параметр, как ид-канала.
    Сейчас, делаю новую софтинку к прибору. Уже на C#. Все хорошо, кроме необходимости объявления 16 статических обработчиков. (с динамическими вылезает проблема access violation, судя по-всему сборщик мусора наглеет) и назначать их через рефлекшн. Причем по-коду обработчики идентичные, отличие только в номере канала. Отсюда вопрос. можно ли при создании инстанса к делегату, использовать функцию имеющую на один параметр больше, и задавать этот параметр при создании.
    Ну что-то вроде приведенного ниже примера:
    Код (C++):
    public unsafe delegate void ci_handler(Int16 ev); // delegate to unmanaged callback.
    public ci_handler[] OnRcv = new ci_handler[16];   // max of 16 channels possible

    // unmanaged callback setting function invoke
    [DllImport("chai.dll", CallingConvention = CallingConvention.Cdecl)]
    unsafe public static extern Int16 CiSetCB(Byte chan, Byte ev, ci_handler handler);

    // test callback handler. must be static, so can not see 'this' and thus do not know it's channel. so we need to add it as additional parameter
    public static void DefaultOnRcv(Byte ev, int channel)
    {
       Writeln(channel.ToString() + ":" + ev.ToString()); // just as HelloWorld
    }

    public void SetCallBack(int ch)
    {
        OnRcv[ch] = new ci_handler( [channel = ch] => DefaultOnRcv ); // needed something like this!!!!
        CiSetCB( ch, (Byte)CiEvents.CIEV_RC, OnRcv[ch] );
    }
    Заранее спасибо за ответы.
     
    #1 EugenOS, 19 июн 2016
    Последнее редактирование: 19 июн 2016
Загрузка...

Поделиться этой страницей