ECMA335 (CLI) 标准 读书笔记——总结CLI类型系统(下)

接上篇:ECMA-335 (CLI) 标准 读书笔记——总结CLI类型系统(上)

 

第二部 15.5.4 数据类型转换

当数据类型转换需要指定平台时,这个标准指定了一个最小的数据类型集,这些类型应该被所有符合CLI的实现所支持。另外的数据类型能通过指定平台的方式来被支持,用定制的属性和(或)定制的修饰语来指定任何要求在特定实现上的特定的操作。

下列的数据类型应该通过所有符合CLI的实现被转换;本地数据类型要实现:

  • 所有的整型数据类型 (int8, int16, unsigned int8, bool, char),包括native整型类型。
  • 枚举,作为基本数据类型。
  • 所有的浮点数据类型(float32 float64),如果它们被CLI托管代码的实现支持。
  • 类型string
  • 上面所有类型的非托管指针

另外,当托管代码转成非托管代码的时候,下列的数据类型应当被支持,但并不需要反向支持(也就是说,当调用非托管方法时看做返回类型,或者当从非托管方法到托管方法的调用时看做参数):

  • 上面任何基于零的一维数组
  • 委托(非托管代码调用委托的机制是平台指定的;它不应该假定委托转换后将产生一个可直接在非托管代码中使用的函数指针)

最后,类型System.Runtime.InteropServices.GCHandle能被用于转换一个对象到非托管代码。该非托管代码接收了一个平台指定的数据类型,该数据类型能被当做一个特定对象的“不透明处理”。参见第四部分。

 

第二部 23.1.16 用于签名中的元素类型

下面的表列出了ELEMENT_TYPE常量的值。它们被广泛地用于元数据签名块,参见第23.2章:

Name

Value

Remarks

ELEMENT_TYPE_END

0x00

Marks end of a list

ELEMENT_TYPE_VOID

0x01

 

ELEMENT_TYPE_BOOLEAN

0x02

 

ELEMENT_TYPE_CHAR

0x03

 

ELEMENT_TYPE_I1

0x04

 

ELEMENT_TYPE_U1

0x05

 

ELEMENT_TYPE_I2

0x06

 

ELEMENT_TYPE_U2

0x07

 

ELEMENT_TYPE_I4

0x08

 

ELEMENT_TYPE_U4

0x09

 

ELEMENT_TYPE_I8

0x0a

 

ELEMENT_TYPE_U8

0x0b

 

ELEMENT_TYPE_R4

0x0c

 

ELEMENT_TYPE_R8

0x0d

 

ELEMENT_TYPE_STRING

0x0e

 

ELEMENT_TYPE_PTR

0x0f

Followed by type

ELEMENT_TYPE_BYREF

0x10

Followed by type

ELEMENT_TYPE_VALUETYPE

0x11

Followed by TypeDef or TypeRef token

ELEMENT_TYPE_CLASS

0x12

Followed by TypeDef or TypeRef token

ELEMENT_TYPE_VAR

0x13

Generic parameter in a generic type definition,

represented as number

ELEMENT_TYPE_ARRAY

0x14

type rank boundsCount bound1 loCount lo1

ELEMENT_TYPE_GENERICINST

0x15

Generic type instantiation. Followed by type typearg-

count type-1 ... type-n

ELEMENT TYPE TYPEDBYREF

0x16

 

ELEMENT_TYPE_I

0x18

System.IntPtr

ELEMENT_TYPE_U

0x19

System.UIntPtr

ELEMENT_TYPE_FNPTR

0x1b

Followed by full method signature

ELEMENT_TYPE_OBJECT

0x1c

System.Object

ELEMENT_TYPE_SZARRAY

0x1d

Single-dim array with 0 lower bound

ELEMENT_TYPE_MVAR

0x1e

Generic parameter in a generic method definition, represented as number

ELEMENT_TYPE_CMOD_REQD

0x1f

Required modifier followed by a TypeDef or TypeRef token

ELEMENT_TYPE_CMOD_OPT

0x20

Optional modifier followed by a TypeDef or TypeRef token

ELEMENT_TYPE_INTERNAL

0x21

Implemented within the CLI

ELEMENT_TYPE_MODIFIER

0x40

Or’d with following element types

ELEMENT_TYPE_SENTINEL

0x41

Sentinel for vararg method signature

ELEMENT_TYPE_PINNED

0x45

Denotes a local variable that points at a pinned object

 

0x50

Indicates an argument of type System.Type.

 

0x51

Used in custom attributes to specify a boxed object

23.3).

 

0x52

Reserved

 

0x53

Used in custom attributes to indicate a FIELD

22.10, 23.3).

 

0x54

Used in custom attributes to indicate a PROPERTY

22.10, 23.3).

 

0x55

Used in custom attributes to specify an enum

23.3).

 

第二部23.2.12 类型

类型在签名中如下编码(I1ELEMENT_TYPE_I1的缩写词,U1ELEMENT_TYPE_U1的缩写词等,参见23.1.16章):

Type ::=

BOOLEAN | CHAR | I1 | U1 | I2 | U2 | I4 | U4 | I8 | U8 | R4 | R8 | I | U

| ARRAY Type ArrayShape (general array, see §23.2.13)

| CLASS TypeDefOrRefEncoded

| FNPTR MethodDefSig

| FNPTR MethodRefSig

| GENERICINST (CLASS | VALUETYPE) TypeDefOrRefEncoded GenArgCount Type *

| MVAR number

| OBJECT

| PTR CustomMod* Type

| PTR CustomMod* VOID

| STRING

| SZARRAY CustomMod* Type (single dimensional, zero-based array i.e., vector)

| VALUETYPE TypeDefOrRefEncoded

| VAR number

非终结符GenArgCount 是一个int32 (压缩的) ,在该签名中指定了泛型参数的数量。

 

第二部 23.2.16 短形式的签名

签名的通用规范在如何编码某些项的时候保留了一些灵活性。例如,以下面的形式编码String似乎是有效的:

long-form: (ELEMENT_TYPE_CLASS, System.String的类型引用 )

short-form: ELEMENT_TYPE_STRING

只有短形式是有效的。下面的表列出了哪些短形式应该被用来替换长形式。(通常,为了紧凑,ELEMENT_TYPE_前缀被省略了,所以VALUETYPE代表了ELEMENT_TYPE_VALUETYPE的短形式

Long Form

Short Form

Prefix

TypeRef to:

 

CLASS

System.String

STRING

CLASS

System.Object

OBJECT

VALUETYPE

System.Void

VOID

VALUETYPE

System.Boolean

BOOLEAN

VALUETYPE

System.Char

CHAR

VALUETYPE

System.Byte

U1

VALUETYPE

System.Sbyte

I1

VALUETYPE

System.Int16

I2

VALUETYPE

System.UInt16

U2

VALUETYPE

System.Int32

I4

VALUETYPE

System.UInt32

U4

VALUETYPE

System.Int64

I8

VALUETYPE

System.UInt64

U8

VALUETYPE

System.IntPtr

I

VALUETYPE

System.UIntPtr

U

VALUETYPE

System.TypedReference

TYPEDBYREF

 

第二部 23.4 Marshalling descriptors

Marshalling Descriptor类似于一个签名——它是一个二进制数据块。描述了当调用或者被非托管代码经过平台调用的时候,一个字段或参数(通常,方法的返回值作为第0个参数)应该如何被转换。

注意一个符合CLI的实现仅仅需要支持更早期特定类型的转换,见15.5.4章。

Marshalling Descriptor使用名字为NATIVE_TYPE_xxx的常量。它们的名字和值如下表:

Name

Value

NATIVE_TYPE_BOOLEAN

0x02

NATIVE_TYPE_I1

0x03

NATIVE_TYPE_U1

0x04

NATIVE_TYPE_I2

0x05

NATIVE_TYPE_U2

0x06

NATIVE_TYPE_I4

0x07

NATIVE_TYPE_U4

0x0b

NATIVE_TYPE_I8

0x09

NATIVE_TYPE_U8

0x0a

NATIVE_TYPE_R4

0x0b

NATIVE_TYPE_R8

0x0c

NATIVE_TYPE_LPSTR

0x14

NATIVE_TYPE_LPWSTR

0x15

NATIVE_TYPE_INT

0x1f

NATIVE_TYPE_UINT

0x20

NATIVE_TYPE_FUNC

0x26

NATIVE_TYPE_ARRAY

0x2a

这个块有下列格式:

MarshalSpec ::=

NativeIntrinsic

| ARRAY ArrayElemType

| ARRAY ArrayElemType ParamNum

| ARRAY ArrayElemType ParamNum NumElem

NativeIntrinsic ::=

BOOLEAN | I1 | U1 | I2 | U2 | I4 | U4 | I8 | U8 | R4 | R8

| LPSTR | LPSTR | INT | UINT | FUNC

 

第三部分 1.1 数据类型

当CTS定义了一个富类型系统,CLS指定了一个能被用于语言互操作的子集时,CLI本身处理一套简单得多的类型集。这些类型包括用户自定义的值类型和内建类型的子集。该子集,统称为“基本CLI类型”,包含了下面的类型:

  • 完整的数字类型子集int32, int64, native intF)。
  • 对象引用(O),被引用的对象类型间无区别。
  • 指针类型(native unsigned int &),被指向的类型无区别。

注意对象引用和指针类型能被赋予值null。这在CLI中被定义为零(所有位全为零的位组合格式)。

【注:至于关于VES在求值栈上的操作,就只有一个浮点类型,VES不关心其大小。VES仅在存储这些值到或者读取这些值从堆,静态,本地变量或者方法参数时,才弄清楚这些数字值的大小。】

 

总结一下:

第二部 7.1章列出了高级语言层面所有CLI支持的内建类型;

第二部 7.4章列出了高级语言层面所有CLI支持的本地类型;

第二部 23.1.16列出了metadata中能以二进制形式记录的内建类型;

第二部 23.4列出了metadata中能以二进制形式记录的本地类型;

 

原文地址:https://www.cnblogs.com/cubean/p/1706671.html