The Metadata API gives developers low-level access to the information encoded in CLI modules: type and methods definitions encoded in metadata as well as access to the CIL code and embedded resources.
Managed developers access this information using either the System.Reflection API or a library like Cecil.
To start using the Metadata API it is necessary to open an assembly or a CIL image (a .dll or .exe file) using one of the CIL image opening API calls.
ECMA CLI images contain four heaps that store different kinds of information, these are:
The ECMA file format also has an extra section called the "#~" stream, this stream is the one that holds the metadata tables. There is a high-level API to get access to the contents of this API, described in the section Metadata Tables.
mono_metadata_guid_heap
meta | metadata context |
index | index into the guid heap. |
mono_metadata_string_heap
meta | metadata context |
index | index into the string heap. |
mono_metadata_blob_heap
meta | metadata context |
index | index into the blob. |
mono_metadata_user_string
meta | metadata context |
index | index into the user string heap. |
US
").
mono_metadata_decode_blob_size
ptr | pointer to a blob object |
rptr | the new position of the pointer |
This decodes a compressed size as described by 23.1.4 (a blob or user string object)
Metadata is encoded in a number of tables included on every CIL image. These tables contain type definitions, member definitions and so on, these constants are defined in the ECMA 335 specification Partition II section 22. The following table shows the C constants defined in the Mono runtime and how they map to the equivalent ECMA CLI metadata table:
ECMA CLI Table Name | C Constant Name | Table Schema (Array Size + Columns Constants) | Assembly | MONO_TABLE_ASSEMBLY |
Array size:
MONO_ASSEMBLY_SIZE
|
AssemblyOS | MONO_TABLE_ASSEMBLYOS |
Array size:
MONO_ASSEMBLYOS_SIZE
|
AssemblyProcessor | MONO_TABLE_ASSEMBLYPROCESSOR | Array
size: MONO_ASSEMBLYPROCESSOR_SIZE
|
AssemblyRef | MONO_TABLE_ASSEMBLYREF |
Array size:
MONO_ASSEMBLYREF_SIZE
|
AssemblyRefProcessor | MONO_TABLE_ASSEMBLYREFPROCESSOR | Array
size: MONO_ASSEMBLYREFPROC_SIZE
|
AssemblyRefOS | MONO_TABLE_ASSEMBLYREFOS |
Array size:
|
ClassLayout | MONO_TABLE_CLASSLAYOUT |
Array size:
MONO_CLASSLAYOUT_SIZE
|
Constant | MONO_TABLE_CONSTANT |
Array size:
MONO_CONSTANT_SIZE
|
CustomAttribute | MONO_TABLE_CUSTOMATTRIBUTE |
Array size:
MONO_CUSTOM_ATTR_SIZE
|
DeclSecurity | MONO_TABLE_DECLSECURITY |
Array size:
MONO_DECL_SECURITY_SIZE
|
EventMap | MONO_TABLE_EVENTMAP |
Array size:
MONO_EVENT_MAP_SIZE
|
EventPtr | MONO_TABLE_EVENT_POINTER |
Array size:
MONO_EVENT_POINTER_SIZE
|
Event | MONO_TABLE_EVENT |
Array size: MONO_EVENT_SIZE
|
ExportedType | MONO_TABLE_EXPORTEDTYPE |
Array size:
MONO_EXPORTEDTYPE_SIZE
|
Field | MONO_TABLE_FIELD |
Array size: MONO_FIELD_SIZE
|
FieldLayoutt | MONO_TABLE_FIELDLAYOUT |
Array size:
MONO_FIELDLAYOUT_SIZE
|
FieldMarshal | MONO_TABLE_FIELDMARSHAL |
Array size:
MONO_FIELD_MARSHAL_SIZE
|
FieldPtr | MONO_TABLE_FIELD_POINTER |
Array size:
MONO_FIELD_POINTER_SIZE
|
FieldRVA | MONO_TABLE_FIELDRVA |
Array size:
MONO_FIELDRVA_SIZE
|
File | MONO_TABLE_FILE |
Array size: MONO_FILE_SIZE
|
GenericParam | MONO_TABLE_GENERICPARAM |
Array size:
MONO_GENERICPARAM_SIZE
|
GenericParamConstraint | MONO_TABLE_GENERICPARAMCONSTRAINT | Array
size: MONO_GENERICPARAMCONSTRAINT_SIZE
|
ImplMap | MONO_TABLE_IMPLMAP |
Array size:
MONO_IMPLMAP_SIZE
|
InterfaceImpl | MONO_TABLE_INTERFACEIMPL |
Array size:
|
ManifestResource | MONO_TABLE_MANIFESTRESOURCE | Array
size: MONO_MANIFESTRESOURCE_SIZE
|
MemberRef | MONO_TABLE_MEMBERREF |
Array size:
MONO_MEMBERREF_SIZE
|
MethodImpl | MONO_TABLE_METHODIMPL |
Array size:
MONO_METHODIMPL_SIZE
|
MethodSpec | MONO_TABLE_METHODSPEC |
Array size:
MONO_METHODSPEC_SIZE
|
MethodSemantics | MONO_TABLE_METHODSEMANTICS | Array
size: MONO_METHOD_SEMA_SIZE
|
Moduleref | MONO_TABLE_MODULEREF |
Array size:
MONO_MODULEREF_SIZE
|
Module | MONO_TABLE_MODULE |
Array size:
MONO_MODULE_SIZE
Columns:
|
TypeRef | MONO_TABLE_TYPEREF |
Array size:
MONO_TYPEREF_SIZE
|
MethodPtr | MONO_TABLE_METHOD_POINTER |
Array size:
MONO_METHOD_POINTER_SIZE
|
Method | MONO_TABLE_METHOD |
Array size:
MONO_METHOD_SIZE
|
NestedClass | MONO_TABLE_NESTEDCLASS |
Array size:
MONO_NESTEDCLASS_SIZE
|
ParamPtr | MONO_TABLE_PARAM_POINTER |
Array size:
MONO_PARAM_POINTER_SIZE
|
Param | MONO_TABLE_PARAM |
Array size: MONO_PARAM_SIZE
|
PropertyMap | MONO_TABLE_PROPERTYMAP |
Array size:
MONO_PROPERTY_MAP_SIZE
|
PropertyPtr | MONO_TABLE_PROPERTY_POINTER | Array
size: MONO_PROPERTY_POINTER_SIZE
|
Property | MONO_TABLE_PROPERTY |
Array size:
MONO_PROPERTY_SIZE
|
StandaloneSig | MONO_TABLE_STANDALONESIG |
Array size:
|
TypeDef | MONO_TABLE_TYPEDEF |
Array size:
MONO_TYPEDEF_SIZE
|
TypeSpec | MONO_TABLE_TYPESPEC |
Array size:
MONO_TYPESPEC_SIZE
|
Each table can contain zero or more rows, you must call the mono_metadata_table_rows to obtain the number of rows in a table, and then you can extract individual row values by using the mono_metadata_decode_row or the mono_metadata_decode_row_col. When decoding rows you must provide an guint32 array large enough to hold as many columns as the table contains.
The metadata tables are stored in the MonoImage, you obtain a pointer to the MonoTableInfo by calling the mono_image_get_table_info and then you can scan those tables, for example:
/* * Dumps a few fields from the AssemblyRef table */ void DumpAssemblyRefs (MonoImage *image) { /* Get a pointer to the AssemblyRef metadata table */ MonoTableInfo *t = mono_image_get_table_info (image, MONO_TABLE_ASSEMBLYREF); /* Fetch the number of rows available in the table */ int rows = mono_table_info_get_rows (t); int i; /* For each row, print some of its values */ for (i = 0; i < rows; i++){ /* Space where we extract one row from the metadata table */ guint32 cols [MONO_ASSEMBLYREF_SIZE]; /* Extract the row into the array cols */ mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE); fprintf (output, "%d: Version=%d.%d.%d.%d\n\tName=%s\n", i + 1, cols [MONO_ASSEMBLYREF_MAJOR_VERSION], cols [MONO_ASSEMBLYREF_MINOR_VERSION], cols [MONO_ASSEMBLYREF_BUILD_NUMBER], cols [MONO_ASSEMBLYREF_REV_NUMBER], mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])); } }
The above program shows the following output when ran on the C# compiler:
1: Version=1.0.5000.0 Name=mscorlib 2: Version=1.0.5000.0 Name=System 3: Version=1.0.5000.0 Name=System.Xml
These are the APIs for dealing with tables:
mono_image_get_table_info
mono_image_get_table_rows
mono_metadata_decode_row_col
t | table to extract information from. |
idx | index for row in table. |
col | column in the row. |
This function returns the value of column col from the idx row in the table t.
mono_metadata_decode_row
t | table to extract information from. |
idx | index in table. |
res | array of res_size cols to store the results in |
This decompresses the metadata element idx in table t into the guint32 res array that has res_size elements
mono_metadata_compute_size
mono_metadata_custom_attrs_from_index
mono_metadata_decode_signed_value
ptr | pointer to decode from |
rptr | the new position of the pointer |
This routine decompresses 32-bit signed values (not specified in the spec)
mono_metadata_decode_value
ptr | pointer to decode from |
rptr | the new position of the pointer |
This routine decompresses 32-bit values as specified in the "Blob and Signature" section (22.2)
mono_metadata_encode_value
This is the low-level API for accessing the metadata images.
mono_pe_file_open
fname | filename that points to the module we want to open |
status | An error condition is returned in this field |
NULL
on error. if
NULL
, then check the value of status for details on the error.
This variant for mono_image_open DOES NOT SET UP CLI METADATA.
It's just a PE file loader, used for FileVersionInfo. It also does
not use the image cache.
mono_metadata_events_from_typedef
mono_metadata_decode_table_row
Same as mono_metadata_decode_row, but takes an IMAGE+TABLE ID pair, and takes uncompressed metadata into account, so it should be used to access the Method, Field, Param and Event tables when the access is made from metadata, i.e. IDX is retrieved from a metadata table, like MONO_TYPEDEF_FIELD_LIST.
mono_metadata_decode_table_row_col
Same as mono_metadata_decode_row_col, but takes an IMAGE+TABLE ID pair, and takes uncompressed metadata into account, so it should be used to access the Method, Field, Param and Event tables.
mono_metadata_field_info
mono_metadata_free_array
mono_metadata_free_marshal_spec
mono_metadata_free_mh
mono_metadata_free_type
mono_metadata_get_constant_index
mono_metadata_get_marshal_info
mono_metadata_implmap_from_method
mono_metadata_interfaces_from_typedef
mono_metadata_locate
meta | metadata context |
table | table code. |
idx | index of element to retrieve from table. |
mono_metadata_locate_token
meta | metadata context |
token | metadata token |
token
.
mono_metadata_methods_from_event
mono_metadata_methods_from_property
mono_metadata_nested_in_typedef
mono_metadata_nesting_typedef
mono_metadata_packing_from_typedef
mono_metadata_properties_from_typedef
mono_metadata_token_from_dor
mono_metadata_translate_token_index
mono_metadata_typedef_from_field
meta | metadata context |
index | FieldDef token |
mono_metadata_typedef_from_method
mono_metadata_type_equal
mono_metadata_type_hash
mono_metadata_declsec_from_index
mono_metadata_free_method_signature
mono_metadata_parse_array
mono_metadata_parse_custom_mod
mono_metadata_parse_field_type
m | metadata context to extract information from |
ptr | pointer to the field signature |
rptr | pointer updated to match the end of the decoded stream |
Parses the field signature, and returns the type information for it.
mono_metadata_parse_marshal_spec
mono_metadata_parse_method_signature
mono_metadata_parse_mh
mono_metadata_parse_param
m | metadata context to extract information from |
ptr | pointer to the param signature |
rptr | pointer updated to match the end of the decoded stream |
Parses the param signature, and returns the type information for it.
mono_metadata_parse_ret_type
mono_metadata_parse_signature
mono_metadata_parse_typedef_or_ref
mono_metadata_parse_type
m | metadata context |
mode | king of type that may be found at ptr |
opt_attrs | optional attributes to store in the returned type |
ptr | pointer to the type representation |
rptr | pointer updated to match the end of the decoded stream |
transient | whenever to allocate the result from the heap or from a mempool |
MonoType
structure representing the decoded type.
Decode a compressed type description found at ptr in m. mode can be one of MONO_PARSE_MOD_TYPE, MONO_PARSE_PARAM, MONO_PARSE_RET, MONO_PARSE_FIELD, MONO_PARSE_LOCAL, MONO_PARSE_TYPE. This function can be used to decode type descriptions in method signatures, field signatures, locals signatures etc.
To parse a generic type, `generic_container' points to the current class'es (the `generic_container' field in the MonoClass) or the current generic method's (stored in image->property_hash) generic container. When we encounter any MONO_TYPE_VAR or MONO_TYPE_MVAR's, they're looked up in this MonoGenericContainer.
LOCKING: Acquires the loader lock.
mono_metadata_generic_class_equal
mono_metadata_generic_class_hash
mono_metadata_generic_class_is_valuetype
mono_ldtoken
mono_ldstr
domain | the domain where the string will be used. |
image | a metadata context |
idx | index into the user string table. |
Implementation for the ldstr opcode.
mono_exception_from_token
image | the Mono image where to look for the class |
token | The type token of the class |
Creates an exception of the type given by token.
mono_opcode_name