2014-01-03 1 views
6

Импорт библиотеки базового типа с использованием инструмента tlbimp.exe всегда создает интерфейс для каждого coclass. Например, этот IDL-описаниеКаковы интерфейсы CoClass в импортированных сборках именно для?

interface IFoo : IUnknown 
{ 
    HRESULT DoSomething(); 
} 

coclass Bar 
{ 
    [default] interface IFoo; 
} 

приводит к:

  • интерфейс, IFoo как представление интерфейса COM,
  • Класс, BarClass как представление COM компонентного класса и
  • интерфейс Bar, аннотированный CoClassAttribute.

Если идентификаторы Bar и IFoo равны. На этой теме: MSDN:

Этот интерфейс имеет тот же IID, что и стандартный интерфейс для coclass. С помощью этого интерфейса клиенты всегда могут регистрироваться как приемники событий.

Это единственное, что я нашел на эту тему. Я знаю, что из-за CoClassAttribute я могу использовать интерфейс для создания экземпляров фактического класса. Я также знаю, что (практически) я могу просто использовать BarClass, чтобы создать новый экземпляр класса. Я не понимаю, почему процесс импорта создает интерфейс Bar, даже если coclass не определяет источник события, и поэтому к нему нельзя подключить приемник событий.

Можно ли удалить в этом примере интерфейс Bar или есть другие риски, которые я еще не рассмотрел?

Например по disassembling the interop assembly.

ответ

5

У вас неправильные имена, что не помогает понять, что происходит. Компонент Bar в библиотеке типов генерирует интерфейс Bar и класс BarClass, нет «FooBar».

Это просто дополнительный клей, который автоматически генерирует библиотеку типов, чтобы сделать код переноса. Особенно важно для кода VB6, он потребовал больших свобод с объектной моделью COM. В программе VB6 используется класс, как будто это настоящий класс с реализацией. В COM нет такой вещи, класс является непрозрачным местом для класса, это интерфейсы, которые выполняют всю работу. VB6 никогда не поддерживал понятие интерфейсов, поэтому прямое моделирование COM в коде было невозможно.

Сам компилятор VB6 генерирует класс кода из ключевого слова Class в коде и генерирует интерфейс, который содержит фактические методы и свойства. Этот интерфейс скрыт, он имеет то же имя класса, но с лидирующим подчеркиванием. По соглашению, это заставляет объектные браузеры скрывать интерфейс. Таким образом, ваш Bar coclass, написанный на VB6, будет генерировать интерфейс _Bar.

Таким образом, конвертированная программа VB6 будет использовать Bar всюду.Это не будет компилироваться, если только «Бар» не будет заменен «IFoo». Синтезированный интерфейс Bar приходит на помощь, избегая необходимости в этом.

Осталось решить две проблемы, исправленные синтетическим типом BarClass. New Bar() не будет компилироваться, поскольку создание экземпляра интерфейса не является законным. Компилятор решает эту проблему, он автоматически заменяет «Bar» на «BarClass». Какова фактическая роль атрибута [CoClass], он предоставляет имя для класса, связанного с интерфейсом. И события - это проблема, они реализованы в COM с помощью dispinterface. Снова отдельный интерфейс с запутанным механизмом под капотом, который подписывает события (IConnectionPoint и др.). Синтетический BarClass делает их реалистичными .NET-событиями.

+0

Я исправил имена в вопросе. Спасибо за Ваш ответ! Поскольку я не переношу приложение VB6, и мой примерный класс выше не определяет события, я думаю, что ваш ответ подразумевает, что я могу удалить интерфейс, отвечая на мой quesiton в последнем предложении. Пожалуйста, исправьте меня, если я ошибаюсь! В противном случае - спасибо за ваши усилия! :) – Carsten