7

次のように CIL で定義された 1 つのフィールドがあります。

.field public int32 modopt(void*) fld

これをアセンブリにコンパイルします。今、私はそれを次のように変更します:

.field public int32 modopt(int16) fld

両方とも、ILDASM が (16 進数で表示されている場合)両方のフィールドを次のように報告することができるようになったのはなぜですか?

Field #1 (04000001)
-------------------------------------------------------
    Field Name: fld (04000001)
    Flags     : [Public]  (00000006)
    CallCnvntn: [FIELD]
    Field type:  CMOD_OPT 1b000001 I4
    Signature : 06 20 06 08 

このコードは、両方のフィールドをまったく同じように検索します (実際には、報告された署名と一致するように 2 番目のフィールドを作成しました)。署名は明らかに 2 番目のフィールドと一致しますが、最初のフィールドの署名は次のようになります06 20 0f 01 08。ここで何が欠けていますか?

編集:

C# はこのタイプのフィールドを生成できず、カスタム型修飾子でサポートされていないポインターおよび配列型に関する例外をスローするため、これによりシグネチャの不一致が明らかに解決されます。しかし、なぜ ILDASM が逆コンパイルできない無効な署名の作成を許可するのかという疑問が残ります。

編集#2:

ILASM が実際に正しい IL を作成しているようです。前回見逃した 16 進ダンプに違いがあります。

//the first assembly
TypeSpec #1 (1b000001)
-------------------------------------------------------
    TypeSpec : Ptr Void
    Signature: 0f 01 

//the second assembly
TypeSpec #1 (1b000001)
-------------------------------------------------------
    TypeSpec : I2
    Signature: 06 

したがって、ILDASM 16 進ダンプには、間違ったメンバー署名を報告するバグがあります (ただし06、間違った署名がどこから来たのか疑問に思います)。

4

1 に答える 1

1

仕様に基づいて手動でフィールド署名を構築してみましょう。まず、フィールド シグネチャは §II.23.2.4 で定義されています。カスタム修飾子が 1 つの場合、次のようになります。

FIELD CustomMod Type

FIELDは 0x06 として定義されているため、次のようになります。

06 CustomMod Type

カスタム修飾子はmodoptであるため、取得します (§II.23.2.7 に基づく):

06 CMOD_OPT TypeDefOrRefOrSpecEncoded Type

CMOD_OPT0x20 (§II.23.1.16):

06 20 TypeDefOrRefOrSpecEncoded Type

TypeSpec0b110 としてエンコードされた 0x1b000001を参照したい( のTypeSpec場合は 10、0x000001 の場合は 1、§II.23.2.8)。これは、単一バイト 0x06 (§II.23.2) に「圧縮」されます。

06 20 06 Type

最後に、タイプはint32= ELEMENT_TYPE_I40x08 (§II.23.2.12 および §II.23.1.16) です。

06 20 06 08

そのため、ILDasm に示されているものとまったく同じ署名が得られます。

于 2015-01-07T23:38:37.237 に答える