Преобразование импортированного члена

В данном разделе описывается преобразование процедурой импорта следующих членов:

  • Методы

  • Свойства

  • События

Программа Tlbimp.exe применяет атрибут DefaultMemberAttribute к любому методу или свойству с идентификатором DispID, равным 0. Обратите внимание, что разработчики на языке C# должны рассматривать эти члены как массивы. Дополнительные сведения см. в документации по языку программирования.

Методы

Когда COM-взаимодействие импортирует COM-тип, создается сигнатура метода .NET Framework, эквивалентная сигнатуре исходного COM-метода. В процессе преобразования параметры, возвращаемые значения и значения HRESULT модели COM преобразуются в соответствующие элементы сигнатуры метода .NET Framework, как показано на следующем рисунке.

Преобразование сигнатуры метода

Преобразование сигнатуры метода

Синтаксис метода можно проверить с помощью обозревателя объектов или отражения, как и в случае с любым другим классом .NET. Если COM-объект возвращает значение HRESULT, представляющее ошибку, то по умолчанию среда выполнения вызывает соответствующее исключение.

Свойства

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

Процедура преобразования библиотеки типов трансформирует методы доступа к свойствам следующим образом:

  • Свойства с атрибутом [propget] становятся управляемыми свойствами того же типа с соответствующим методом get_propertyname.

  • Свойства с атрибутом [propput] или [propputref] становятся управляемыми свойствами того же типа, с соответствующим методом, называющимся set_propertyname.

  • Свойства с обоими атрибутами [propput] и [propputref] преобразуются в:

    • управляемые свойства того же типа, что и атрибут [propputref], с соответствующим методом set_propertyname;

    • другой метод доступа с тем же типом, что и атрибут [propput], с именем let_propertyname.

В следующей библиотеке типов показаны исходные свойства.

Представление библиотеки типов

interface ISample : IDispatch {
    [propget]    HRESULT prop1([out, retval] short *pVal);
    [propput]    HRESULT prop1([in] short newVal);

    [propget]    HRESULT prop2([out, retval] INew **pVal);
    [propputref] HRESULT prop2([in] INew *newVal);

    [propget]    HRESULT prop3([out, retval] INew **ppINew);
    [propput]    HRESULT prop3([in] BSTR text);
    [propputref] HRESULT prop3([in] INew *pINew);
}

Преобразованные свойства появляются в следующем фрагменте кода Visual Basic 2005.

Public Property 
    Get Prop1() As Integer … End Get    
    Set Prop1(val as Integer) … End Set
End Property

Public Property 
    Get Prop2() As INew … End Get 
    Set Prop2(val as INew) … End Set
End Property

Public Property
    Get Prop3() As INew … End Get 
    Set Prop3(val as INew) … End Set 
End Property

Public let_prop3(String as Text)

События

В библиотеке COM-типов могут быть определены интерфейсы, используемые для событий. Компонентный класс, размещенный в библиотеке и являющийся источником событий, может определять интерфейс события с помощью атрибута [source]. Приемник событий реализует интерфейс, а источник событий использует его. Интерфейсы точек подключения COM, не описанные в библиотеке типов, связывают приемник событий с источником событий.

В следующем примере кода IDL класс Button реализует интерфейс IButton и порождает события для интерфейса IButtonEvents.

interface IButton {
    HRESULT Init();
}

interface IButtonEvents {
    HRESULT Click([in] int x, [in] int y);
    HRESULT Resize([out, retval] int *pRetval};
}

coclass Button {
    [default] interface IButton;
    [default, source] interface IButtonEvents;
}

Модель событий .NET Framework существенно отличается от модели событий COM, основанной на точках подключения. Вместо использования точек подключения COM управляемые классы принимают события путем передачи делегата источнику событий. Служба COM-взаимодействия связывает эти две различные модели событий.

В процессе импорта программа Tlbimp.exe создает несколько типов, с помощью которых управляемое приложение может принимать события, порождаемые неуправляемыми классами, с использованием модели событий .NET. В приведенной ниже последовательности действий программа Tlbimp.exe создает классы и интерфейсы для класса Button, используемого в предыдущем примере.

  1. Процедура импорта создает тип-делегат для каждого события в интерфейсе событий. Имя делегата состоит из имени интерфейса событий приемника, символа подчеркивания, имени события и слова EventHandler. Например, в библиотеке типов, показанной в предыдущем примере, событие Click становится делегатом IButtonEvents_ClickEventHandler.

    ' A delegate for each event.
    Delegate Sub IButtonEvents_ClickEventHandler(ByVal x As Integer, _
             ByVal y As Integer)
    Delegate Function IButtonEvents_ResizeEventHandler() As Integer
    
    // A delegate for each event.
    delegate void IButtonEvents_ClickEventHandler(int x, int y);
    delegate int IButtonEvents_ResizeEventHandler();
    

    Обратите внимание, что сигнатура делегата получена путем прямого преобразования сигнатуры неуправляемого метода.

  2. Программа Tlbimp.exe импортирует интерфейс по умолчанию обычным способом, не изменяя имя интерфейса. В этом примере для интерфейса используется имя IButton.

    ' Direct import of original default interface.
    Public Interface IButton
        Sub Init()
    End Interface
    
    // Direct import of original default interface. 
    public interface IButton {
        void Init();
    }
    
  3. Программа Tlbimp.exe импортирует интерфейс событий обычным способом, не изменяя имя интерфейса. В этом примере для интерфейса используется имя IButtonEvent.

    ' Direct import of original event interface. 
    ' Not of interest to managed sinks.
    Public Interface IButtonEvents
        Sub Click(ByVal x As Integer, ByVal y As Integer)
        Function Resize() As Integer
    End Interface
    
    // Direct import of original event interface.
    // Not of interest to managed sinks.
    public interface IButtonEvents {
        void Click(int x, int y);
        int Resize();
    }
    
  4. Программа Tlbimp.exe также создает второй интерфейс событий, для обозначения которого используется имя исходного интерфейса с суффиксом "_Event". Этот второй интерфейс событий содержит в качестве членов события Click и Resize. Он также содержит методы add и remove для делегатов событий. В этом примере для интерфейса используется имя IButtonEvents_Event.

    ' Modified version of the event interface with events
    ' for managed sinks.
    
    Public Interface IButtonEvents_Event
            Sub Click As IButtonEvents_Click
            Function Resize() As IButtonEvents_Resize
            Sub add_Click(ByVal Click As IButtonEvents_ClickEventHandler)
            Sub remove_Click(ByVal Click As _
                   IButtonEvents_ClickEventHandler)
            Sub add_Resize(ByVal Resize As _
                   IButtonEvents_ResizeEventHandler)
            Sub remove_Resize(ByVal Resize As _
                   IButtonEvents_ResizeEventHandler)
        End Interface
    // Modified version of the event interface with events 
    // for managed sinks.
    public interface IButtonEvents_Event {
       IButtonEvents_Click Click;
       IButtonEvents_Resize Resize;
       void add_Click(IButtonEvents_ClickEventHandler );
       void remove_Click(IButtonEvents_ClickEventHandler );
       void add_Resize(IButtonEvents_ResizeEventHandler );
       void remove_Resize(IButtonEvents_ResizeEventHandler );
    }
    
    ПримечаниеПримечание

    В тех редких случаях, когда требуется приведение к интерфейсу событий, выполняется приведение к интерфейсу, созданному программой Tlbimp.exe, а не к исходному интерфейсу.Например, необходимо выполнить приведение к IButtonEvents_Event, а не к IButtonEvents.

  5. Программа Tlbimp.exe импортирует компонентный класс, порождающий события, чтобы гарантировать включение всех интерфейсов, реализованных явным образом, и добавляет слово Class к имени исходного класса. Например, компонентный класс Button преобразуется в ButtonClass. Программа Tlbimp.exe также создает интерфейс компонентного класса, имеющий то же имя класса, что и компонентный класс и реализующий интерфейс событий с суффиксом _Event.

    ' This is the imported coclass interface.
    ' Note the underscore in IButtonEvents_Event.
        Public Interface Button
            Inherits IButton
            Inherits IButtonEvents_Event
        End Interface
    
        Public Class ButtonClass
            Implements Button
            Implements IButton
            Implements IButtonEvents_Event
            Sub Init()
            End Sub 'Init
        End Class
    
    // This is the imported coclass interface.
    // Note the underscore in IButtonEvents_Event.
    public interface Button:IButton, IButtonEvents_Event {} 
    
    public class ButtonClass:Button,IButton,IButtonEvents_Event 
    {
    void Init(){}
    }
    

См. также

Основные понятия

Преобразование импортированной библиотеки

Преобразование импортированного модуля

Преобразование импортированного типа

Преобразование импортированного параметра

Другие ресурсы

Обзор преобразования библиотеки типов в сборку