Archivos de metadatos de Windows (WinMD)
Windows Runtime API (WinRT) .winmd
se describen en archivos de metadatos legibles por máquina con la extensión (también conocida como Windows metadatos). Estas herramientas y proyecciones de lenguaje usan estos archivos de metadatos para habilitar la proyección de idioma.
Notas generales
Windows incluye metadatos para todas las API de WinRT proporcionadas por el sistema. Windows proporciona API para ayudar a las proyecciones de lenguaje en la resolución de espacios de nombres y tipos que necesitan estos metadatos en tiempo de ejecución. El SDK Windows proporciona una copia de los metadatos del sistema en un único archivo para su uso por las proyecciones de lenguaje que necesitan estos metadatos en tiempo de compilación.
Los terceros pueden desarrollar sus propias API de WinRT que pueden participar en la proyección de idioma como lo hacen las API proporcionadas por el sistema. Las API de WinRT de terceros deben proporcionar metadatos igual que las API del sistema. Windows API para el espacio de nombres y la resolución de tipos funcionan en metadatos de terceros como lo hacen para los metadatos del sistema.
Todos los tipos públicos de un archivo WinMD deben ser tipos WinRT y deben llevar la marca tdWindowsRuntime (detalles sobre las marcas de tipo que se deben seguir). Los archivos WinMD pueden incluir metadatos para tipos que no son de WinRT. Los tipos que no son de WinRT en un archivo WinMD no deben ser públicos. La semántica de los tipos que no son de WinRT está definida por la implementación y está fuera del ámbito de este documento.
Todos los miembros de la interfaz pública (métodos, propiedades y eventos) de los tipos de WinRT deben ser miembros de la interfaz de WinRT. Los tipos de WinRT pueden incluir metadatos para miembros de interfaz que no son de WinRT. Es posible que los miembros de la interfaz que no son de WinRT no sean públicos. La semántica de los miembros de la interfaz que no son de WinRT está definida por la implementación y está fuera del ámbito de este documento.
Archivos WinMD
Formato de archivo WinMD
Los archivos WinMD usan el mismo formato de archivo físico que los ensamblados de Common Language Runtime (CLR), tal y como se define en la especificación ECMA-335. Sin embargo, aunque el formato de archivo físico es el mismo, las reglas para combinaciones válidas de datos son diferentes para los archivos WinMD y los ensamblados CLR. En este documento se enumeran las diferencias entre los archivos WinMD y los ensamblados CLR.
Los archivos WinMD proporcionados por el sistema son metadatos puros. Los archivos WinMD de terceros pueden contener código. En concreto, los archivos WinMD administrados incluyen código de Lenguaje intermedio de Microsoft (MSIL), al igual que los ensamblados CLR tradicionales.
Cada archivo WinMD contiene las definiciones de cero o más tipos de WinRT. Los archivos WinMD vacíos son técnicamente válidos.
No hay ninguna restricción específica de WinRT en la arquitectura peKind o de máquina que se muestra en un WinMD.
La cadena de versión de WinMD debe contener "Windows Runtime 1.2".
Nombre de archivo WinMD
El nombre (sin extensión) de un archivo WinMD debe ser una coincidencia sin mayúsculas y minúsculas con la columna name de la tabla de ensamblados dentro del archivo WinMD. Por ejemplo, el archivo "Foo.Bar.winmd" debe tener "Foo.Bar" en la columna name de la tabla de ensamblados. Dado que el sistema de archivos no distingue mayúsculas de minúsculas, la mayúscula y minúscula del nombre de archivo puede diferir del valor de columna del nombre de la tabla de ensamblados.
Todos los tipos de WinRT de un archivo WinMD determinado deben estar en un espacio de nombres que coincida con el nombre del archivo WinMD y el valor de columna del nombre de la tabla de ensamblados. Dado que el sistema de archivos no distingue mayúsculas de minúsculas, el caso del nombre de archivo puede diferir del espacio de nombres de todos los tipos de WinRT de un archivo WinMD determinado. El espacio de nombres de todos los tipos de WinRT de un WinMD determinado debe coincidir exactamente con el valor de columna de nombre de tabla de ensamblado (es decir, con distingue mayúsculas de minúsculas). Por ejemplo, todos los tipos del archivo con "Foo.Bar" en la columna name de la tabla de ensamblados deben estar en el espacio de nombres "Foo.Bar". Los tipos pueden ser elementos secundarios directos de este espacio de nombres (por ejemplo, Foo.Bar.MyType) o en subnodos de este espacio de nombres (por ejemplo, Foo.Bar.Baz.MyType). El nombre del archivo debe ser "Foo.Bar.winmd", pero puede variar en el caso, es decir, "foo.bar.winmd" y "FOO. BAR. WINMD" también se permitiría como nombres de archivo para este archivo de metadatos.
Composición de WinMD
Los metadatos de todos los tipos del sistema se reparten entre varios archivos .winmd. Un paquete AppX puede incluir cero o más archivos .winmd que describen componentes de WinRT de terceros que se incluyen en el paquete de aplicación.
En todos los archivos .winmd proporcionados por el sistema o incluidos con una aplicación determinada, los metadatos de cada tipo de WinRT deben almacenarse en el archivo WinMD, con el nombre más largo que coincida con el espacio de nombres del tipo. Todos los tipos que son elementos secundarios directos de un espacio de nombres determinado deben encontrarse en el mismo archivo. Por ejemplo, si un paquete AppX incluye archivos Foo.winmd y Foo.Bar.winmd, el tipo Foo.Bar.Baz.MyType debe encontrarse en el archivo Foo.Bar.winmd, ya que es el archivo con el nombre de archivo que coincide con el espacio de nombres más largo para el tipo del paquete.
Redirección de TypeDef
Los archivos de metadatos proporcionados por el sistema nunca hacen referencia directamente a TypeDefs. Incluso cuando se hace referencia a un tipo definido en el mismo archivo de metadatos, los archivos de metadatos del sistema siempre hacen referencia a un TypeRef que, a su vez, hace referencia a TypeDef. Esto se hace para admitir el redireccionamiento de tipos CLR (proyectando IVectorT<> como IListT<>, por ejemplo).
Los archivos de metadatos de terceros pueden usar TypeDef directamente o pueden redirigir todas las referencias de tipo a través de un TypeRef similar al modo en que lo hacen los archivos de metadatos del sistema.
Codificación del sistema de tipos
WinRT usa todos los tipos de este documento del espacio de nombres System del ensamblado mscorlib como marcadores. Estos tipos se usan para indicar información sobre los tipos y nunca se deben resolver. Esto incluye (entre otros) System.Object, System.Guid, System.ValueType, System.Enum, System.MulticastDelegate y System.Attribute. Tenga en cuenta que estos nombres se han elegido para la compatibilidad con CLR. La definición de CLR de estos tipos forma parte de su sistema de tipos y no tiene nada que ver con WinRT.
Tenga en cuenta que muchas de las construcciones descritas aquí usan la sintaxis de C#. Esto se debe simplemente a que es conveniente representar determinadas construcciones de metadatos Common Language Infrastructure (CLI) mediante la sintaxis de C#. Las construcciones reales son construcciones puras de metadatos de la CLI.
Espacio de nombres
WinRT codifica el espacio de nombres y el nombre local de un tipo en una sola cadena delimitada por períodos. Por ejemplo, el tipo definido en este fragmento de código es "Windows. Foundation.ISimpleInterface".
namespace Windows {
namespace Foundation {
interface ISimpleInterface {
HRESULT Method1(int paramOne);
};
};
};
Para la optimización de espacio, la tabla TypeDef de los metadatos de la CLI proporciona columnas independientes para el nombre de tipo y el nombre del espacio de nombres. Sin embargo, en el nivel de API, la propiedad TypeDef solo expone el nombre de tipo.
Tipos fundamentales
Todos los tipos fundamentales de WinRT excepto Guid tienen valores constantes explícitos para su uso en blobs de metadatos de la CLI y otras referencias de tipo. Estos valores constantes se describen en la partición 2, sección 23.1.16 de la especificación de la CLI.
Tipo de WinRT | Nombre del tipo de elemento de la CLI | Valor de tipo de elemento de la CLI |
---|---|---|
Int16 | ELEMENT_TYPE_I2 | 0x06 |
Int32 | ELEMENT_TYPE_I4 | 0x08 |
Int64 | ELEMENT_TYPE_I8 | 0x0a |
UInt8 | ELEMENT_TYPE_U1 | 0x05 |
UInt16 | ELEMENT_TYPE_U2 | 0x07 |
UInt32 | ELEMENT_TYPE_U4 | 0x09 |
UInt64 | ELEMENT_TYPE_U8 | 0x0b |
Single | ELEMENT_TYPE_R4 | 0x0c |
Doble | ELEMENT_TYPE_R8 | 0x0d |
Char16 | ELEMENT_TYPE_CHAR | 0x03 |
Boolean | ELEMENT_TYPE_BOOL | 0x02 |
String | ELEMENT_TYPE_STRING | 0x0e |
Puesto que no tiene ningún valor constante ELEMENT_TYPE_*, los GUID se representan en metadatos como TypeRef al tipo System.Guid desde el ensamblado mscorlib.
Enumeraciones
Las enumeraciones se representan como una fila en la tabla TypeDef (ECMA II.22.37) con las columnas establecidas de la siguiente manera.
- Banderas. Establezca en Public | Sealed | tdWindowsRuntime (0x4101).
- Name (Nombre). Índice del montón de cadenas que contiene el nombre del tipo.
- Espacio de nombres. Índice del montón de cadenas que contiene el espacio de nombres del tipo .
- Extiende. Se establece en un TypeRef que hace referencia a la clase System.Enum en el ensamblado mscorlib.
- FieldList. Índice de la tabla Field, que marca el primero de una ejecución contigua de campos propiedad de este tipo.
- MethodList. Debe estar vacío.
Una enumeración tiene un único campo de instancia que especifica el tipo entero subyacente para la enumeración, así como cero o más campos estáticos; uno para cada valor de enumeración definido por el tipo de enumeración.
El tipo entero subyacente de la enumeración aparece como la primera fila de la tabla Field (ECMA II.22.15) asociada al tipo (es decir, la a la que se hace referencia en la columna FieldList especificada anteriormente). Las columnas de la tabla Field para el tipo de enumeración son las siguientes.
- Marcas: Private | SpecialName | RTSpecialName (0x601).
- Name: índice del montón de cadenas que contiene el nombre "value__".
- Firma: índice en el montón de blobs que contiene un blob FieldSig (ECMA II.23.2.4) donde type se establece en ELEMENT_TYPE_I4 o ELEMENT_TYPE_U4, ya que los valores de enumeración de WinRT deben ser enteros de 32 bits con signo o sin signo.
Después de la definición del valor de enumeración, aparece una definición de campo para cada uno de los valores de la enumeración .
- Marcas: | static | literal | hasdefault (0x8056).
- Name: índice del montón de cadenas que contiene el nombre del valor de enumeración.
- Firma: índice en el montón de blobs que contiene un blob FieldSig (ECMA II.23.3.4) con el tipo establecido en typeDef del tipo de enumeración.
Para cada definición de valor de enumeración, hay una fila correspondiente en la tabla Constant (ECMA II.22.9) para almacenar el valor entero del valor de enumeración.
- Type (Tipo). Un byte para representar el tipo subyacente de la enumeración, ya sea ELEMENT_TYPE_I4 o ELEMENT_TYPE_U4, seguido de un relleno cero de bytes según la especificación ecma.
- Primario: indexe en la tabla de campos que contiene el registro de valor de enumeración asociado.
- Valor: indexe en la tabla de blobs que contiene el valor entero del valor de enumeración.
Además, System.FlagsAttribute debe agregarse a la fila TypeDef de enumeración para cualquier enumeración con un tipo UInt32 subyacente. FlagsAttribute no debe agregarse a la fila TypeDef de enumeración para enumeraciones con un tipo Int32 subyacente.
Para todas las enumeraciones proporcionadas por el sistema, versionAttribute debe agregarse a la fila TypeDef de enumeración. Opcionalmente, versionAttribute se puede agregar a cualquiera de las filas field estáticas. Si está presente, el valor de versión de VersionAttribute en cualquier fila de campo de enumeración debe ser mayor o igual que el valor de VersionAttribute en la fila TypeDef de enumeración.
Estructuras
Los structs se implementan como una fila en la tabla TypeDef (ECMA II.22.37) con las columnas establecidas de la manera siguiente.
- Marcas: | Sealed | Secuencias | tdWindowsRuntime (0x4109).
- Name: índice del montón de cadenas que contiene el nombre del tipo.
- Espacio de nombres: índice del montón de cadenas que contiene el espacio de nombres del tipo.
- Extiende : se establece en un TypeRef que hace referencia a la clase System.ValueType en el ensamblado mscorlib.
- FieldList: índice de la tabla Field, que marca el primero de una ejecución contigua de campos propiedad de este tipo.
- MethodList: debe estar vacío.
Los structs tienen una o varias entradas de tabla Field.
- Marcas: pública.
- Nombre: índice del montón de cadenas que contiene el nombre del campo.
- Firma: índice en el montón de blobs que contiene un blob FieldSig (ECMA II.23.2.4) con el tipo establecido en el token de metadatos para el tipo de campo.
- Los campos de estructura deben ser tipos fundamentales, enumeraciones u otros structs.
Para todos los structs proporcionados por el sistema, versionAttribute debe agregarse a la fila TypeDef de struct.
Delegados
Los delegados se implementan como una fila en la tabla TypeDef (ECMA II.22.37) con las columnas establecidas de la siguiente manera.
- Marcas: se establece en | Sealed | tdWindowsRuntime (0x4101).
- Name: índice del montón de cadenas que contiene el nombre del tipo.
- Espacio de nombres: índice del montón de cadenas que contiene el espacio de nombres del tipo.
- Extiende: se establece en un TypeRef que hace referencia a la clase System.MulticastDelegate en el ensamblado mscorlib.
- FieldList: debe estar vacío.
- MethodList: índice de la tabla MethodDef (ECMA II.22.26), que marca la primera de una ejecución contigua de métodos propiedad de este tipo.
Las filas TypeDef de los delegados deben tener guidAttribute.
Los delegados tienen exactamente dos entradas de tabla MethodDef. La primera define un constructor. Este constructor es un marcador de compatibilidad, por lo que usa construcciones que no son de WinRT, como int nativo, y parámetros que no son in
ni out
. Los delegados de WinRT no tienen este método de constructor.
- RVA: 0 (se trata de una construcción abstracta).
- ImplFlags: runtime (0x03).
- Marcas: | hidebysig | nombre especial | RTSpecialName (0x1881).
- Name: índice de la tabla de cadenas que contiene el nombre ".ctor".
- Firma: índice en el montón de blobs que contiene un blob MethodDefSig (ECMA II.23.2.1) para un método con un objeto e int nativo en parámetros y sin valor devuelto.
- ParamList: índice de la tabla Param (ECMA II.22.33) que contiene el primero de una ejecución de filas param asociadas a este método. Cada fila de la tabla Param contiene la siguiente información.
- Parámetro object
- Secuencia 1
- Nombre "object"
- Marcas: none (0x00)
- Parámetro Native Int
- Secuencia 2
- Nombre "method"
- Marcas: none (0x00)
- Parámetro object
La segunda entrada MethodDef define el método Invoke.
- RVA: 0 (se trata de una construcción abstracta)
- ImplFlags: runtime (0x03)
- Marcas: | Virtual | HideBySig | specialname (0x08C6)
- Name: índice de la tabla de cadenas que contiene el nombre "Invoke"
- Firma: índice en el montón de blobs que contiene un blob MethodDefSig (ECMA II.23.2.1) que contiene los tipos de parámetro y el tipo de valor devuelto del delegado. Si el delegado tiene parámetros, el blob MethodDefSig debe hacer referencia a cada uno de los parámetros de tipo de delegados a través de tipo codificado GENERICINST (según ECMA II.23.2.12). Detalles sobre los delegados con parámetros que se deben seguir.
- ParamList: índice de la tabla Param (ECMA II.22.33) que contiene el primero de una ejecución de filas param asociadas a este método. Cada fila de la tabla Param contendrá la siguiente información.
- Marcas: dentro o fuera según corresponda para el parámetro
- Secuencia: orden de secuencia del parámetro. Cero está reservado para el valor devuelto del método
- Name: índice en el montón de cadenas que contiene el nombre del parámetro Para todos los delegados proporcionados por el sistema, versionAttribute debe agregarse a la fila TypeDef del delegado.
Delegados con parámetros
Los delegados con parámetros tienen los siguientes requisitos adicionales.
- El nombre de un delegado con parámetros se anexa con un subrayado y un número que representa el número de parámetros de tipo que tiene el delegado con parámetros. Por ejemplo, el Windows. El tipo Foundation.EventHandlerT<> se almacena en metadatos con el nombre Windows. Foundation.EventHandler'1.
- Los delegados con parámetros tienen una fila en la tabla GenericParam (ECMA II.22.20) para cada parámetro de tipo con las columnas establecidas de la manera siguiente.
- Number: índice del parámetro genérico, numerado de izquierda a derecha, empezando por cero.
- Marcas: Ninguna.
- Propietario: indexe en la tabla TypeDef de la fila que contiene la interfaz.
- Nombre: indexe en el montón de cadenas que contiene el nombre del parámetro genérico.
La tabla TypeSpec (ECMA II.23.2.14) se usa para definir instancias de delegados con parámetros. Estos TypeSpecs se pueden usar en firmas de método de forma similar a TypeRefs.
Interfaces
Las interfaces se implementan como una fila en la tabla TypeDef (ECMA II.22.37) con las columnas establecidas de la manera siguiente.
- Flags:
- interfaz | public | abstract | tdWindowsRuntime (0x40A1) o
- interfaz | NotPublic| abstract | tdWindowsRuntime (0x40A0)
- Nombre: índice de la tabla de cadenas que contiene el nombre de la interfaz.
- Espacio de nombres: índice en el montón de cadenas que contiene el espacio de nombres del tipo.
- Extiende: null.
- FieldList: debe estar vacío.
- MethodList: índice de la tabla MethodDef, que marca la primera de una ejecución contigua de métodos propiedad de este tipo. Los detalles sobre el contenido de la tabla MethodDef se detallan en las subsecciones de la sección actual.
Las filas TypeDef de interfaces deben tener un GuidAttribute y un VersionAttribute.
Cualquier interfaz de WinRT con visibilidad privada debe tener un único ExclusiveToAttribute. Cualquier interfaz de WinRT con visibilidad pública no debe tener ExclusiveToAttribute. Si está presente, ExclusiveToAttribute debe hacer referencia a una clase en tiempo de ejecución.
Las interfaces necesarias para una interfaz se representan mediante filas en la tabla InterfaceImpl (ECMA II.22.23) con las columnas establecidas de la manera siguiente.
- Clase: índice de la tabla TypeDef para la fila que contiene la interfaz .
- Interfaz: índice de la tabla TypeDef, TypeRef o TypeSpec que especifica la interfaz necesaria. Tenga en cuenta que, en los archivos de metadatos proporcionados por el sistema, nunca será typeDef aunque la interfaz necesaria esté definida en el mismo archivo de metadatos. Consulte la sección TypeDef Redirection (Redirección de TypeDef) para obtener más detalles.
Interfaces parametrizadas
Las interfaces parametrizadas cumplen los siguientes requisitos adicionales.
El nombre de una interfaz parametrizada se anexa con un subrayado y un número que representa el número de parámetros de tipo que tiene el delegado con parámetros. Por ejemplo, el Windows. El tipo Foundation.Collections.IVectorT<> se almacena en metadatos con el nombre Windows. Foundation.Collections.IVector'1.
Las interfaces parametrizadas tienen una fila en la tabla GenericParam (ECMA II.22.20) para cada parámetro de tipo con las columnas establecidas de la manera siguiente.
- Number: índice del parámetro genérico, numerado de izquierda a derecha, empezando por cero.
- Marcas: Ninguna.
- Propietario: indexe en la tabla TypeDef de la fila que contiene la interfaz.
- Nombre: indexe en el montón de cadenas que contiene el nombre del parámetro genérico.
La tabla TypeSpec (ECMA II.23.2.14) se usa para definir instancias de interfaces parametrizadas. Estos TypeSpecs se pueden usar en firmas de método e implementaciones de interfaz de forma similar a TypeRefs.
Miembros de interfaz
Parámetros de matriz
Al codificar un parámetro Array para cualquier tipo de miembro de interfaz, el parámetro de longitud de matriz que precede inmediatamente al parámetro de matriz se omite tanto del blob MethodDefSig como de la tabla params.
La dirección del parámetro de matriz se codifica directamente en metadatos. La dirección del parámetro de longitud de la matriz se puede inferir como se muestra a continuación.
- Si el parámetro de matriz es un parámetro in, el parámetro de longitud de la matriz también debe ser un parámetro in.
- Si el parámetro de matriz es un parámetro out y no lleva el marcador BYREF, la longitud de la matriz es un parámetro in.
- Si el parámetro de matriz es un parámetro out y lleva el marcador BYREF, la longitud de la matriz es un parámetro out.
Métodos
Para modelar mejor la proyección esperada de métodos, así como la compatibilidad con CLR, el valor devuelto HRESULT necesario no se codifica en los metadatos. En su lugar, el parámetro out que se va a usar como valor devuelto se codifica como valor devuelto en methodDefSig. Para los métodos que no declaran un parámetro out que se va a usar como valor devuelto, methodDefSig debe declarar el tipo de valor devuelto como void (según ECMA II.23.2.11).
Cada método de una interfaz se representará como una fila en la tabla MethodDef. Cada fila methoddef contendrá la siguiente información.
- RVA: 0x00
- ImplFlags: 0x00
- Marcas: public | Virtual | HideBySig | Resumen | NewSlot | Instancia (0x5c6)
- Nombre: índice de la tabla de cadenas que contiene el nombre del método
- Firma: índice en el montón de blobs que contiene un blob MethodDefSig (ECMA II.23.2.1) que contiene los tipos de parámetro y el tipo de valor devuelto del método. Si la interfaz tiene parámetros, el blob MethodDefSig debe hacer referencia a cada uno de los parámetros de tipo de la interfaz a través del tipo codificado GENERICINST (según ECMA II.23.2.12). Detalles sobre las interfaces parametrizadas que se deben seguir.
- ParamList: índice de la tabla Param (ECMA II.22.33) que contiene el primero en una ejecución de filas param asociadas a este método.
Cada parámetro del método (más el valor devuelto si se especifica) tendrá una fila correspondiente en la tabla Param (ECMA II.22.33).
- Marcas: ninguna, dentro o fuera según corresponda para el parámetro .
- Los valores devueltos siempre son ninguno
- Otros parámetros siempre están dentro o fuera
- Secuencia: orden de secuencia del parámetro.
- Cero está reservado para el valor devuelto del método
- Name: indexa en el montón de cadenas que contiene el nombre del parámetro.
Opcionalmente, cada método puede tener un OverloadAttribute que lleve el nombre de método único (dentro del ámbito de la interfaz ). Opcionalmente, cada método puede tener un DefaultOverloadAttribute que indica qué método sobrecargado de la misma aridad (número de parámetros in) debe proyectarse en lenguajes débilmente con tipo dinámico.
Propiedades
Cada propiedad de una interfaz se define como filas en las tablas Property (ECMA II.22.34), PropertyMap (ECMA II.22.35), MethodSemantics (ECMA II.22.28) y MethodDef (ECMA II.22.26).
Cada interfaz con una o varias propiedades se representará como una sola fila en la tabla PropertyMap que contiene la siguiente información.
- Primario: índice de la tabla TypeDef que contiene la interfaz que contiene las propiedades.
- PropertyList: índice de la tabla Property que contiene el primero de una ejecución de filas asociada a este tipo.
Cada propiedad se representará como una sola fila en la tabla Property que contiene la siguiente información
- Marcas: Ninguna.
- Nombre: índice en el montón de cadenas que contiene el nombre de la propiedad.
- Tipo: índice en el montón de blobs que contiene un blob PropertySig (ECMA II.23.2.5) que contiene la información de tipo de la propiedad.
Cada propiedad se representará como una o dos filas en la tabla MethodDef. Las propiedades de solo lectura se representan como un único método con el prefijo "get_", mientras que las propiedades de lectura y escritura se representan como dos métodos, uno con el prefijo "get_" y el otro con el prefijo "put_". La firma del método get no toma ningún parámetro y devuelve un valor del tipo de la propiedad. La firma del método set toma un único parámetro del tipo de propiedad y no devuelve nada.
Las filas MethodDef de la propiedad contienen lo siguiente.
- RVA: 0
- ImplFlags: None
- Marcas: public | virtual | HideBySig | newSlot | abstract | specialname (0xDC6)
- Nombre: índice de la tabla de cadenas que contiene "get_<PropertyName>" o "put_<PropertyName>" según corresponda
- Firma: índice en el montón de blobs que contiene un blob MethodDefSig (ECMA II.23.2.1) que contiene los tipos de parámetro y el tipo de valor devuelto del método, como se describió anteriormente.
- ParamList: índice de la tabla Param (ECMA II.22.33) que contiene el primero en una ejecución de filas param asociadas a este método. Los valores de la tabla Param se especifican en los métodos anteriores.
Cada fila MethodDef de la propiedad tendrá una fila asociada en la tabla MethodSemantics que contiene la siguiente información.
- Semántica: Getter o Setter según corresponda.
- Método: indexe en la tabla MethodDef que contiene el método getter o setter.
- Asociación: indexe en la tabla Property que contiene la propiedad .
Eventos
Cada evento de una interfaz se define como filas en las tablas Event (ECMA II.22.13), EventMap (ECMA II.22.12), MethodSemantics (ECMA II.22.28) y MethodDef (ECMA II.22.26).
Cada interfaz con uno o varios eventos se representará como una sola fila en la tabla EventMap que contiene la siguiente información.
- Primario: índice de la tabla TypeDef que contiene la interfaz que contiene las propiedades.
- EventList: índice de la tabla Event que contiene el primero de una ejecución de filas asociada a este tipo.
Cada evento se representará como una sola fila en la tabla Event que contiene la siguiente información.
- EventFlags: None.
- Nombre: índice en el montón de cadenas que contiene el nombre de la propiedad.
- EventType: TypeDefOrRef que indexa en la tabla adecuada que contiene el tipo delegado del evento.
Cada evento se representará como dos filas en la tabla MethodDef, una con el prefijo "add_" para agregar agentes de escucha de eventos y otra con el prefijo "remove_" para quitar agentes de escucha de eventos. El método add toma una instancia de delegado y devuelve un Windows. Foundation.EventRegistrationToken que representa el registro de eventos. El método remove toma eventRegistrationToken devuelto por el método add para anular el registro del evento.
Las filas MethodDef del evento contienen lo siguiente.
- RVA: 0
- ImplFlags: None
- Marcas: public | Final | virtual | hidebysig | newslot | specialname (0x09e6)
- Nombre: índice de la tabla de cadenas que contiene "add_<PropertyName>" o "remove_<PropertyName>" según corresponda.
- Firma: índice en el montón de blobs que contiene un blob MethodDefSig (ECMA II.23.2.1) que contiene los tipos de parámetro y valor devuelto del método, tal como se describe a continuación.
- Add_ método toma un único parámetro del tipo delegado y devuelve un Windows. Foundation.EventRegistrationToken.
- Remove_ método toma un único Windows. Parámetro Foundation.EventRegistrationToken y no devuelve nada.
- ParamList: índice de la tabla Param (ECMA II.22.33) que contiene el primero en una ejecución de filas param asociadas al método . Los valores de la tabla Param se especifican en los métodos anteriores.
Ambas filas de MethodDef para el evento tendrán una fila asociada en la tabla MethodSemantics que contiene la siguiente información.
- Semántica: AddOn o RemoveOn según corresponda.
- Método: indexe en la tabla MethodDef que contiene el método add o remove listener.
- Asociación: indexe en la tabla Event que contiene el evento.
Clases en tiempo de ejecución
Las clases en tiempo de ejecución se implementan como una fila en la tabla TypeDef (ECMA II.22.37) con las columnas establecidas de la manera siguiente.
- Marcas: todas las clases en tiempo de ejecución deben incluir las marcas public, auto layout, class y tdWindowsRuntime.
- Las clases estáticas solo llevan la marca abstracta. Todas las demás clases no llevan la marca abstracta.
- Las clases que no admiten composición llevan la marca sellada. Las clases que admiten composición no llevan la marca sellada.
- Nombre: índice de la tabla de cadenas que contiene el nombre de clase.
- Espacio de nombres: índice en el montón de cadenas que contiene el espacio de nombres del tipo.
- Extiende: un índice en typeRef que hace referencia a una clase que admite composición o a System.Object en mscorlib.
- FieldList: debe estar vacío.
- MethodList: índice de la tabla MethodDef, que marca la primera de una ejecución contigua de métodos propiedad de este tipo. A continuación se detallan los detalles sobre el contenido de la tabla MethodDef.
Para todas las clases proporcionadas por el sistema, versionAttribute debe agregarse a la fila TypeDef de la clase.
Interfaces implementadas
Las interfaces implementadas por clases en tiempo de ejecución se representan mediante filas en la tabla InterfaceImpl (ECMA II.22.23) con las columnas establecidas de la manera siguiente.
- Clase: índice de la tabla TypeDef de la fila que contiene el tipo.
- Interfaz: índice de la tabla TypeDef, TypeRef o TypeSpec que especifica la interfaz implementada. Tenga en cuenta que, en los archivos de metadatos proporcionados por el sistema, nunca será typeDef aunque la interfaz necesaria esté definida en el mismo archivo de metadatos. Consulte la sección TypeDef Redirection (Redirección de TypeDef) para obtener más detalles.
Las clases en tiempo de ejecución deben especificar DefaultAttribute exactamente en una de sus filas interfaceImpl.
Las clases en tiempo de ejecución pueden especificar OverridableAttribute o ProtectedAttribute en cualquiera de sus filas interfaceImpl. Es posible que no especifiquen OverridableAttribute y ProtectedAttribute en la misma fila.
Opcionalmente, versionAttribute se puede agregar a cualquiera de las filas interfaceImpl de la clase. El valor de versión de VersionAttribute en las filas interfaceImpl de cualquier clase debe ser mayor o igual que el valor de VersionAttribute en la fila TypeDef de la clase.
Interfaces estáticas
Las clases en tiempo de ejecución tienen cero o más atributos personalizados StaticAttribute. Es legal especificar más de un atributo personalizado StaticAttribute, siempre y cuando cada uno tenga parámetros especificados diferentes. Cualquier atributo StaticAttribute aparecerá como una fila en la tabla CustomAttribute con la siguiente información.
- Primario: clase en tiempo de ejecución a la que está asociado StaticAttribute.
- Tipo: referencia al archivo .ctor de StaticAttribute.
- Valor: blob de atributo personalizado que contiene el parámetro de interfaz estática System.Type y el parámetro de versión Uint32.
Activación
Las clases en tiempo de ejecución tienen cero o más atributos personalizados ActivatableAttribute. Es legal especificar más de un atributo personalizado ActivatableAttribute, siempre y cuando cada uno tenga parámetros especificados diferentes. Cualquier Elemento ActivatableAttributes aparecerá como una fila en la tabla CustomAttribute con la siguiente información.
- Primario: clase en tiempo de ejecución a la que está asociado ActivatableAttribute.
- Tipo: referencia a uno de los dos .ctors de ActivatableAttribute.
- Activación directa: el archivo .ctor que toma solo el parámetro de versión Uint32.
- Activación de fábrica: el .ctor que toma el parámetro de interfaz de generador System.Type y el parámetro de versión Uint32.
- Valor: blob de atributo personalizado que contiene el parámetro de interfaz de generador System.Type (si se proporciona) y el parámetro de versión Uint32.
Composición
Las clases en tiempo de ejecución tienen cero o más atributos personalizados de ComposableAttribute. Es legal especificar más de un atributo personalizado ComposableAttribute, siempre y cuando cada uno tenga parámetros especificados diferentes. Cualquier Elemento ComposableAttribute aparecerá como una fila en la tabla CustomAttribute con la siguiente información.
- Primario: la clase en tiempo de ejecución composableAttribute está asociada a .
- Tipo: referencia al archivo .ctor de ComposableAttribute.
- Valor: blob de atributo personalizado que contiene el parámetro de interfaz de generador de composición System.Type, un valor de enumeración CompositionType (público o protegido) y el parámetro de versión Uint32.
Métodos de clase
Una clase en tiempo de ejecución tiene una fila en la tabla MethodDef para cada método en cada interfaz asociada a la clase . Esto incluye interfaces miembro (normales, protegidas y reemplazables), interfaces estáticas, interfaces de generador de activación e interfaces de generador que admiten composición. Además, una clase que admite la activación directa también tendrá una fila en la tabla MethodDef para indicarlo.
Miembros de la interfaz de miembro
Cada método de una interfaz miembro (incluidas las interfaces protegidas y reemplazables) se representa mediante una fila en la tabla MethodDef de la clase. La tabla methodDef de la clase contiene una copia exacta de la información de MethodDef de la interfaz declaratoria original, incluidas las filas de la tabla Param y los atributos personalizados, con las siguientes excepciones.
- Las clases en tiempo de ejecución pueden especificar nombres alternativos para los métodos definidos en interfaces miembro.
- Los métodos de las clases en tiempo de ejecución no obtienen la marca Abstract.
- Los métodos de las clases en tiempo de ejecución obtienen la marca Runtime MethodImpl.
- Los métodos de interfaces no reemplazables obtienen además la marca Final. Los métodos de interfaces reemplazables no obtienen la marca Final.
Cada fila de la tabla MethodDef de una clase de una interfaz miembro se vuelve a conectar al método de interfaz que definió originalmente el método a través de una entrada de la tabla MethodImpl (ECMA II.22.27) con valores como se muestra a continuación.
- Clase: índice de la tabla TypeDef que hace referencia a la clase que lleva el método (tenga en cuenta que este índice no está sujeto a la redirección de TypeDef).
- MethodBody: índice de la tabla MethodDef que hace referencia al método de clase .
- MethodDeclaration: índice de la tabla MethodDef o MemberRef que hace referencia al método de interfaz declarado originalmente.
Miembros de interfaz estática
Cada método de una interfaz estática se representa mediante una fila en la tabla MethodDef de la clase. La tabla methodDef de la clase contiene una copia exacta de la información de MethodDef de la interfaz declaratoria original, incluidas las filas de la tabla Param y los atributos personalizados, con las siguientes excepciones.
- Los miembros estáticos no obtienen las marcas Virtual, Abstract, NewSlot e Instance.
- Los miembros estáticos obtienen las marcas Static y Class.
- Los métodos estáticos de las clases en tiempo de ejecución obtienen la marca Runtime MethodImpl.
Miembros de activación
Las clases que admiten la activación directa sin parámetros tienen una fila de constructor en la tabla MethodDef de la clase con los siguientes valores de columna.
- RVA: 0x00
- ImplFlags: Runtime
- Marcas: public | HideBySig | SpecialName | RtSpecialName | Ejemplo
- Nombre: índice de la tabla de cadenas que contiene ".ctor".
- Firma: índice en el montón de blobs que contiene un blob MethodDefSig (ECMA II.23.2.1) que no contiene parámetros y devuelve NULL
- ParamList: debe estar vacío
Las clases que admiten la activación de fábrica tienen una fila de constructor en la tabla MethodDef de la clase para cada método de cada interfaz de generador implementada con los siguientes valores de columna.
- RVA: 0x00
- ImplFlags: Runtime
- Marcas: | HideBySig | SpecialName | RtSpecialName | Ejemplo
- Nombre: índice de la tabla de cadenas que contiene ".ctor".
- Firma: índice en el montón de blobs que contiene un blob MethodDefSig (ECMA II.23.2.1) que contiene los parámetros de entrada y devuelve null.
- ParamList: puntero a la tabla Params con una fila para cada parámetro, copiada exactamente de la tabla params para el método de fábrica que declara originalmente.
Miembros de composición
Las clases que admiten la activación del generador de composición tienen una fila de constructor en la tabla MethodDef de la clase para cada método de cada interfaz de generador implementada con los siguientes valores de columna.
- RVA: 0x00
- ImplFlags: Runtime
- Marcas: | HideBySig | SpecialName | RtSpecialName | Ejemplo
- Nombre: índice de la tabla de cadenas que contiene ".ctor".
- Firma: índice en el montón de blobs que contiene un blob MethodDefSig (ECMA II.23.2.1) que contiene los parámetros de entrada personalizados y devuelve NULL. El parámetro IInspectable* de control [in] y el parámetro IInspectable** [out] no delegable** no se reflejan en la firma del método.
- ParamList: puntero a la tabla Params con una fila para cada parámetro excepto el parámetro IInspectable* [in] de control y el parámetro IInspectable** [out] no delegante, copiados exactamente de la tabla params para el método de fábrica que declara originalmente.
Atributos personalizados
Los atributos personalizados tienen cero o más métodos de constructor, cada uno con cero o más parámetros donde el tipo de parámetro se limita a los tipos fundamentales, enumeraciones y System.Type. Cada constructor del atributo personalizado aparece como una fila en MethodDef con la siguiente información.
- RVA (también conocido como dirección virtual relativa): null
- ImplFlags: None
- Marcas: | HideBySig | specalname | RTSpecialName (0x1886)
- Name: índice de la tabla de cadenas que contiene el nombre ".ctor".
- Firma: índice en el montón de blobs que contiene un blob MethodDefSig (ECMA II.23.2.1) que contiene los tipos de parámetro y el tipo de valor devuelto del método.
- ParamList: índice de la tabla Param (ECMA II.22.33) que contiene el primero de una ejecución de filas param asociadas a este método.
Los atributos personalizados de las construcciones de metadatos se almacenan como filas en la tabla CustomAttribute (ECMA II.22.10) con las columnas establecidas de la siguiente manera.
- Primario: indexa en la tabla de metadatos a la que está asociado el atributo personalizado.
- Tipo: indexa en la tabla MethodDef o MemberRef que contiene una referencia al constructor del tipo de atributo.
- Valor: indexe en el montón de blobs que contiene parámetros de atributo posicionales y con nombre (ECMA II.23.2). Tenga en cuenta que, dado que no se permite que los atributos personalizados de WinRT tengan propiedades, el blob de atributos personalizados nunca contendrá argumentos con nombre de estilo PROPERTY.