Overview of Metadata

Metadata is used to describe runtime types (classes, interfaces, and value types), fields, and methods, as well as internal implementation and layout information that is used by the common language runtime (CLR). The runtime uses metadata to JIT-compile Microsoft intermediate language (MSIL), load classes, execute code, and interoperate with the COM classic or native world. The metadata is included with every CLR component, and is available to the runtime, tools, and services.

This overview contains the following sections:

  • The Metadata API

  • Comparison with Reflection Services

  • Scope

  • Error Checking

  • Related Topics

The Metadata API

All manipulation of metadata is performed through the metadata API, which insulates a client (tools and services) from the underlying data structures. The metadata API provides a pluggable persistence format that enables runtime binary representations, COM classic type libraries, and other formats to be transferred to or from memory transparently.

The metadata API includes interfaces that emit (that is, generate) and import metadata. A client can emit or import metadata in the following ways:

  • Compilers and tools emit metadata by calling the emit APIs. Metadata is emitted during the compilation and linking process. RAD tools emit metadata as a part of building components or applications. The API members write to and read from in-memory data structures. At save time, these in-memory structures are compressed and persisted in binary format into the target compilation unit (.obj file), executable (.exe) file, or standalone metadata binary file. When multiple compilation units are linked to form an EXE or DLL, the emit API members provide a method to merge the metadata sections from each compilation unit into a single integrated metadata binary file.

  • The loader and other runtime tools and services import metadata by calling API members to obtain information about components so that tasks such as loading and activation can be completed.

Back to top

Comparison with Reflection Services

The metadata API enables a component's metadata to be accessed without requiring the class to be loaded by the runtime. The API is designed specifically to maximize performance and minimize overhead. The metadata engine makes the data available but stops short of providing direct access to the in-memory data structures. In contrast, when a class is loaded at run time, the loader imports the metadata into its own data structures, which you can browse by using the runtime's reflection services.

The reflection services do much more work than the metadata API. For example, they automatically walk the inheritance hierarchy to obtain information about inherited methods and fields. The metadata API returns only the direct member declarations for a given class and requires the API client to make additional calls to walk the hierarchy and enumerate inherited methods. The reflection services approach exposes a higher-level view of metadata, whereas the metadata API approach puts the API client in complete control of walking the data structures.

Back to top

Scope

At any given time you might have several distinct areas of memory that contain metadata. For example, you might have one area that maps all of the metadata from an existing module on disk. At the same time, you might be emitting metadata into a separate area that you will later save as a module into a file.

Note

The word module here means a file that contains metadata. Typically it will be an .obj, .exe, or .dll file that contains both metadata and Microsoft intermediate language (MSIL) code, but it can also be a file that contains only metadata.

Each separate area of metadata in memory is referred to as a scope. Each scope corresponds to one module. Modules are often saved as files on disk, but this is not required. For example, scripting tools frequently generate metadata that is never persisted into a file.

The term scope is used because it represents the region within which metadata tokens are defined. For example, a metadata token with value N identifies details about a class definition within a given scope. However, a metadata token with the same value N might correspond to a completely different set of details for a different scope.

To establish a metadata scope in memory, you call the CComPtrBase::CoCreateInstance method of the IMetaDataDispenser interface. This method creates a new scope or opens an existing set of metadata structures from a file or memory location. With each call to the IMetaDataDispenser::DefineScope or the IMetaDataDispenser::OpenScope method, the caller specifies which API to receive:

  • The IMetaDataEmit interface enables tools to write to a metadata scope.

  • The IMetaDataImport interface enables tools to read from a metadata scope.

Back to top

Error Checking

The metadata API performs a minimum of semantic error checking. The metadata API methods assume that the tools and services that emit metadata are enforcing the object system rules that are outlined in the common type system, and that any additional checking by the metadata engine during development time is superfluous.

Back to top

Title

Description

Metadata Tokens

Provides information about metadata tokens, which are used to identify abstractions, and explains how they are used with the metadata API.

Coding Conventions for Metadata API

Describes the coding conventions that are used by the metadata API.

Metadata Interfaces

Describes the unmanaged interfaces that provide access to the metadata exposed by the .NET Framework types, methods, fields, and so on.

Metadata Global Static Functions

Describes the unmanaged global static functions that the metadata API uses.

Metadata Enumerations

Describes the unmanaged enumerations that the metadata API uses.

Metadata Structures

Describes the unmanaged structures that the metadata API uses.

Metadata Unions

Describes the unmanaged unions that the metadata API uses.

Back to top