Conversión de miembros importados

Actualización: noviembre 2007

En este tema se describe cómo el proceso de importación convierte los miembros siguientes:

  • Métodos

  • Propiedades

  • Eventos

Tlbimp.exe aplica DefaultMemberAttribute a cualquier método o propiedad con un identificador DispID de 0. Tenga en cuenta que los programadores de C# deben tratar estos miembros como matrices. Para obtener información adicional, consulte la documentación del lenguaje de programación.

Métodos

Cuando la interoperabilidad COM importa un tipo COM, produce un prototipo de método .NET Framework equivalente al prototipo de método COM original. Durante el proceso de conversión, asigna parámetros, valores devueltos y resultados HRESULT COM a los de un prototipo de método .NET Framework, como se muestra en la siguiente ilustración.

Conversión de prototipo de método

Puede examinar la sintaxis del método con un visor de objetos o usando la reflexión, al igual que con cualquier otra clase .NET. De manera predeterminada, cuando el objeto COM devuelve un error de resultado HRESULT, el motor de tiempo de ejecución produce la excepción correspondiente.

Propiedades

Los programadores de COM pueden declarar propiedades y métodos en las interfaces. Todas las propiedades tienen sus métodos de descriptor de acceso correspondientes para establecer u obtener los valores de las propiedades. Cuando el proceso de importación convierte en metadatos la descripción de una biblioteca de tipos de una interfaz con propiedades, crea una propiedad y uno o varios métodos de descriptor de acceso para dicha propiedad.

El proceso de conversión de la biblioteca de tipos transforma los métodos de descriptor de acceso de la propiedad de las siguientes maneras:

  • Las propiedades con el atributo [propget] se convierten en propiedades administradas del mismo tipo, con un método correspondiente denominado get_propertyname.

  • Las propiedades con los atributos [propput] o [propputref] se convierten en propiedades administradas del mismo tipo, con un método correspondiente denominado set_propertyname.

  • Las propiedades que tienen los dos atributos, [propput] y [propputref] se convierten en:

    • Propiedades administradas del mismo tipo que el atributo [propputref], con un método correspondiente denominado set_propertyname.

    • Otro método de descriptor de acceso con el mismo tipo que el atributo [propput], denominado let_propertyname.

En la siguiente biblioteca de tipos se muestran las propiedades originales.

Representación de biblioteca de tipos

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);
}

Las propiedades convertidas aparecen en el fragmento de código Visual Basic 2005 siguiente.

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)

Eventos

Las bibliotecas de tipos COM pueden definir interfaces que se usan para eventos. Dentro de la biblioteca, una coclase que es el origen de eventos puede identificar la interfaz de eventos buscando el atributo [source]. Un receptor de eventos implementa la interfaz y un origen de eventos la consume. Las interfaces de punto de conexión COM, que no se describen en la biblioteca de tipos, conectan el origen de eventos con el receptor de eventos.

En el siguiente ejemplo de código IDL, la clase Button implementa la interfaz IButton y origina los eventos en la interfaz 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;
}

El modelo de eventos .NET es muy distinto del modelo de puntos de conexión COM. Las clases administradas que reciben eventos lo hacen pasando un delegado al origen de eventos, en lugar de usar puntos de conexión COM. El servicio de interoperabilidad COM sirve de puente entre estos dos diferentes modelos de eventos.

Durante la importación, Tlbimp.exe crea varios tipos que permiten que una aplicación administrada reciba eventos originados por clases no administradas mediante el modelo de eventos .NET. En la siguiente secuencia de pasos, Tlbimp.exe genera clases e interfaces para la clase Button mostrada en el ejemplo anterior.

  1. El proceso de importación crea un tipo de delegado de cada evento en la interfaz del evento. Los nombres de delegados están formados por la interfaz del receptor de eventos, un carácter de subrayado, el nombre del evento y la palabra EventHandler. Por ejemplo, en la biblioteca de tipos del ejemplo anterior, el evento Click se convierte en el delegado 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();
    

    Tenga en cuenta que el prototipo del delegado es una traducción directa del prototipo de método no administrado.

  2. Tlbimp.exe importa la interfaz predeterminada de la forma habitual, sin cambiarle el nombre a la interfaz. En este ejemplo, la interfaz se denomina 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 importa la interfaz de eventos de la forma habitual, conservando el nombre de la interfaz. En este ejemplo, la interfaz se denomina 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 también crea una segunda interfaz de eventos, designada por el sufijo "_Event" agregado al nombre de la interfaz original. Esta segunda interfaz de eventos tiene los eventos Click y Resize como miembros. También tiene los métodos add y remove para los delegados de eventos. En este ejemplo, la interfaz se denomina 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 );
    }
    
    Nota:

    En el caso poco frecuente de que sea necesario convertir a la interfaz de eventos, se convierte a la interfaz que Tlbimp.exe produce, en vez de a la interfaz original. Por ejemplo se debe convertir a IButtonEvents_Event, no a IButtonEvents.

  5. Tlbimp.exe importa la coclase que es el origen de eventos para asegurar la inclusión de todas las interfaces implementadas explícitamente, y agrega el nombre de clase original con Class. Por ejemplo, la coclase Button se convierte en ButtonClass. Tlbimp.exe también crea una interfaz de coclase con el mismo nombre que la coclase, que implementa la interfaz del evento con el sufijo _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(){}
    }
    

Vea también

Conceptos

Conversión de bibliotecas importadas

Conversión de módulos importados

Conversión de tipos importados

Conversión de parámetros importados

Otros recursos

Resumen de la conversión de bibliotecas de tipos en ensamblados