gpt4 book ai didi

.net - 如何找到泛型参数的 TypeSpec

转载 作者:行者123 更新时间:2023-12-04 21:30:05 25 4
gpt4 key购买 nike

一些初步信息

给定以下 C# 函数:

public static void func<T>(T t)
{
System.Console.WriteLine(t);
}

它被编译成以下 CIL:
.method public hidebysig static void  func<T>(!!T t) cil managed
{
ldarg.0
box !!T
call void [mscorlib]System.Console::WriteLine(object)
ret
}

上述方法的签名是 10 01 01 01 1E 00在哪里:

10 - 调用约定 (IMAGE_CEE_CS_CALLCONV_GENERIC)
01 - 函数泛型参数计数(为 1)
01 - 函数参数计数(为 1)
01 - 返回类型 (ELEMENT_TYPE_VOID)
1E - 第一个参数类型 (ELEMENT_TYPE_MVAR)
00 - 上述 MVAR 的索引(为 0)

另请参阅以下指令及其实际字节码:

盒子 !!T - 8C 1B000001
1B000001指向 TypeSpec 表中的第一个条目,该条目指向 blob 02 1E 00在哪里:

02 - Blob 长度
1E - 类型类型 (ELEMENT_TYPE_MVAR)
00 - 上述 MVAR 的索引(为 0)

正如我们所看到的,方法签名以描述性的方式包含泛型参数,其中我们拥有实际的类型签名。
但是,当使用需要 TypeDef/Ref/Spec 的 OpCode 时,会提供 TypeSpec,并且 TypeSpec 指向带有类型信息的签名。

所以我的问题是:
我正在编写一个执行一些 IL 重写的分析器,并且给定函数签名,我想将一些 OpCodes 添加到将使用参数进行操作的函数体中。

使用 IMetaDataImport2接口(interface),如何获取给定泛型参数所需的 TypeSpec token ?

我可以看到 2 个选项:
  • 遍历 EnumTypeSpecs 直到找到匹配
  • 的签名
  • 使用 IMetaDataEmit接口(interface)创建一个新的 TypeSpec

  • 但是,出于显而易见的原因,我想避免这两个选项并选择一个更明智的选择。

    最佳答案

    所以我最终接受了我的第一个建议。
    我想这并不理想,但它确实有效。

    这是代码,如果有人感兴趣(省略错误处理):

    HCORENUM typeSpecEnum = NULL;
    mdTypeSpec typeSpec = mdTypeSpecNil;
    ULONG outNum = -1;

    // Loop through enum
    while (true)
    {
    // Get next enum
    HRESULT hr = pMetadataImport->EnumTypeSpecs(&typeSpecEnum, &typeSpec, 1, &outNum);
    if (hr == S_FALSE && outNum == 0) // According to doc, this means no more. End loop
    break;

    // Get the signature of this typespec
    PCCOR_SIGNATURE curSpecSig = NULL;
    ULONG curSpecSigLen = -1;
    pMetadataImport->GetTypeSpecFromToken(typeSpec, &curSpecSig, &curSpecSigLen);

    if (curSpecSigLen == <my_len> && memcmp(curSpecSig, <my_sig>, <my_len>) == 0)
    ; // Token found
    else
    typeSpec = mdTypeSpecNil; // Reset and goto next token
    }

    pMetadataImport->CloseEnum(typeSpecEnum); // Don't forget to close enum

    关于.net - 如何找到泛型参数的 TypeSpec,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54888459/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com