Самый простой способ реализации событий .NET для C ++ - PullRequest
0 голосов
/ 20 февраля 2012

У меня есть библиотека .NET, которая должна быть доступна для взаимодействия COM, включая некоторые асинхронные операции. Как таковой, мне нужно реализовать события. Реализация событий из C # кажется простой:

[ComVisible(true)]
[Guid("...")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(IClass1Event))]
public class Class1: IClass1
{
    public delegate Int32 IntIntFunc(Int32 arg);
    public event IntIntFunc Event;

    public Int32 RaiseEvent(Int32 param)
    {...}
}

[ComVisible(true)]
[Guid("...")]
public interface IClass1
{
    Int32 RaiseEvent(Int32 param);
}

[ComVisible(true)]
[Guid("...")]
public interface IClass1Event
{
    Int32 Event(Int32 param);
}

Но у меня проблемы с реализацией приемника событий C ++. Различные примеры, от которых я сталкивался, варьируются от простого IConnectionPoint::Advise до простого «использования VB», но я сталкиваюсь с любыми проблемами, пытающимися их реализовать (и нет, я не могу использовать VB) - либо ATL отказывается внедрять AddRef для меня, или я не могу понять VTables своим умом (к сожалению, я очень разбираюсь в фреймворках C). У меня нет информации о том, какой фреймворк предпочтительнее, только этот клиент - C ++.

Итак, мой вопрос: каков был бы самый простой способ представить события .NET в C ++, и, следовательно, какой самый простой способ реализовать приемник тестов?

P.S .: Мне действительно нужен интерфейс событий, чтобы быть IDispatch?

1 Ответ

1 голос
/ 20 февраля 2012

C ++ vtables очень просты, если вы знакомы с COM. Microsoft в значительной степени определила их идентичность. Другими словами, таблица MSVC ++ для class IUnknown является двоичной, как и таблица функций COM interface IUnknown.

.

Теперь вы, кажется, наткнулись на IConnectionPoint::Advise. Это понятно. Это похоже на интерфейс, который вы должны реализовать, но это не так. Это интерфейс, реализованный источником события. Вы используете его, чтобы сообщить источнику, какой приемник использовать.

Чтобы увидеть, что происходит, передайте фиктивный объект IUnknown на IConnectionPoint::Advise и установите точку останова на IUnknown::QueryInterface. Вы увидите запрос источника события для IClass1Event, конечно же, по GUID. Теперь, когда вы реализуете это, вы можете вернуть его из IUnknown::QueryInterface.

Вам не нужно реализовывать интерфейс IDispatch. .Net может обойтись без; это старая Visual Basic 6, которая нуждается в этом. Это потому, что VB6 слабо типизирован и требует позднего связывания.

Больше материалов для чтения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...