Преобразование импортированного члена
Обновлен: Ноябрь 2007
В данном разделе описывается преобразование процедурой импорта следующих членов:
Методы
Свойства
События
Программа 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 класс Buttonn реализует интерфейс 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, используемого в предыдущем примере.
Процедура импорта создает тип-делегат для каждого события в интерфейсе событий. Имя делегата состоит из имени интерфейса событий приемника, символа подчеркивания, имени события и слова 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();
Обратите внимание, что подпись делегата получена путем прямого преобразования подписи неуправляемого метода.
Программа 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(); }
Программа 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(); }
Программа 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.
Программа 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(){} }
См. также
Основные понятия
Преобразование импортированной библиотеки
Преобразование импортированного модуля
Преобразование импортированного типа
Преобразование импортированного параметра