如何转换方法签名数据:
20 03 01 12 55 11 61 09
(IOutputStream, CompressAlgorithm, UInt32)
或
20 01 01 12 55
(IOutputStream)
我正在查看Windows元数据(.winmd-.tlb的后继)。
我可以得到:
但是我不知道如何获得方法参数的类型。
例如Windows.Storage.Compression.Compressor constructor方法具有3个参数:
//Windows.Storage.Compression.Compressor (@02000019)
public class Compressor
{
public Compressor(
IntPtr underlyingStream,
IntPtr algorithm,
Intptr blockSize); // (@060000A0)
}
注意:该参数不是实际上 IntPtr
。那是为了加强我不知道如何找出实际类型的问题。
Windows.Storage.Compression.Compressor 类的标识符为@20000019
。
.ctor
方法的标识符为@060000A0
。
IMetadataImport.GetMethodProps方法返回有关该方法的信息:
".ctor"
0x00001886
(mdHideBySig,mdReuseSlot,mdSpecialName,mdPublic,mdRTSpecialName) 20 03 01 12 55 11 61 09
0
(对于.winmd文件,为0,因为没有代码) 您会注意到20 03 01 12 55 11 61 09
的签名。 (我认为)这是该方法的编码参数的 number 和 type 。
给出方法ID,然后可以使用IMetadataImport.EnumParams枚举方法参数列表。
您还可以挖掘WinMD数据库本身:
方法(表0x06)
- **Rid:** @060000A0
- **RVA (iULONG):** 0
- **ImplFlags (iUSHORT):** 0x0003
- **Flags (iUSHORT):** 0x1886
- **Name (iSTRING):** ".ctor"
- **Signature (iBLOB):** 20 03 01 12 55 11 61 09
- **ParamList (iRid (0x08)):** @080000B6
Param(表0x08)
| Rid | Flags (iUSHORT) | Sequence (iUSHORT) | Name (iSTRING) |
|-----------|-----------------|--------------------|------------------|
| @080000B6 | 0x0001 | 1 | underlyingStream |
| @080000B7 | 0x0001 | 2 | algorithm |
| @080000B8 | 0x0001 | 3 | blockSize |
但是最终没有人返回参数类型的类型或类型引用。
我唯一能想到的是类型是用二进制方法签名编码的。查看两个构造函数的签名:
20 01 01 12 55 : IOutputStream
20 03 01 12 55 11 61 09 : IOutputStream, CompressAlgorithm, UInt32
第一个.ctor具有1个参数,第二个.ctor具有3个参数:
20 01 01 12 55 (one parameter)
20 03 01 12 55 11 61 09 (three parameters)
^
|
number of parameters?
因此可能会将其余数字保留为类型:
20 01 01 12 55 : IOutputStream
20 03 01 12 55 11 61 09 : IOutputStream, CompressAlgorithm, UInt32
^
|
|
number of parameters
.winmd本身具有三种引用类型中的两种:
@010000015
@010000018
某人必须已经弄清楚了方法二进制签名意味着的含义。
以前,我可以decode the binary signature的 [GuidAttribute] :
01 00 1D 22 30 CA D9 86 FB 40 A2 6B D4 4E B7 CF 08 EA 00 00
{CA30221D-86D9-40FB-A26B-D44EB7CF08EA}
在任何地方都没有记录。这只是一个幸运的猜测。
但是我必须假设这都记录在某处; (仅在回答此问题时),在有人回答后,在此页面上。 (而不是在没有解释的情况下对它进行投票-无肠的w夫)
14.7 Plnvoke的方法签名
对 DefineMethod 的调用包含一个名为pvSig的参数,该参数采用 方法的签名。此Blob指定方法的签名-用于 每个参数,以及返回类型(如果有)。该Blob的格式已定义 下面。本节总结了专用于PInvoke的签名的详细信息:
- 所有数据类型都必须是托管数据类型,即使它们最终会在 PInvoke调度,作为非托管函数的参数
- PInvoke提供简单(非结构)的默认自动封送处理 参数,以及struct参数中的简单字段。选择默认值 使用有关托管数据类型声明,目标平台和 方法级别的ansi / unicode / auto属性。 (如果需要,可以覆盖此默认封送处理-请参见 SetFieldMarshal )
- 在方法签名中,应将struct参数声明为承载布局信息的CLR类或值类型(我们在此将其称为“格式化类型” 上面的讨论)。