c# - 什么是 (fnptr)* 类型以及如何创建它?

标签 c# .net reflection clr cil

以下 IL 代码创建一个名为 (fnptr)* 的 Type 实例( token 0x2000000 - 无效,模块 mscorlib.dll)。

ldtoken method void* ()*
call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)

这种类型的目的是什么?是否可以在不编写任何 IL 代码的情况下在 C# 中创建此类型实例,也许使用反射? token 上的 Module.ResolveType 抛出 ArgumentOutOfRangeException

编辑:

很明显 (fnptr) 类型是 IL 方法指针类型的内部 CLR 类型表示,尽管在删除最后一个 * 时,它只是返回 IntPtr.

编辑#2:

(fnptr) 来自一个可以在 SSCLI 中看到的函数typestring.cpp:

// ...or function pointer
else if (ty.IsFnPtrType())
{
    // Don't attempt to format this currently, it may trigger GC due to fixups.
    tnb.AddName(L"(fnptr)");
}

为什么基本的 fnptr 返回 IntPtr 可以在 typehandle.cpp 中看到:

OBJECTREF TypeHandle::GetManagedClassObject() const
{

[...]

        switch(GetInternalCorElementType()) {
        case ELEMENT_TYPE_ARRAY:
        case ELEMENT_TYPE_SZARRAY:
        case ELEMENT_TYPE_BYREF:
        case ELEMENT_TYPE_PTR:
            return ((ParamTypeDesc*)AsTypeDesc())->GetManagedClassObject();

        case ELEMENT_TYPE_VAR:
        case ELEMENT_TYPE_MVAR:
            return ((TypeVarTypeDesc*)AsTypeDesc())->GetManagedClassObject();

            // for this release a function pointer is mapped into an IntPtr. This result in a loss of information. Fix next release
        case ELEMENT_TYPE_FNPTR:
            return TheIntPtrClass()->GetManagedClassObject();

        default:
        _ASSERTE(!"Bad Element Type");
        return NULL;
        }
    }
}

看来他们忘记修复它了。

最佳答案

我真的不知道你在问什么,也不知道你为什么认为有什么问题。 (fnptr)* 是指向非托管函数指针的指针的类型名称。它在 CLR 中得到特殊处理确实很奇怪,我怀疑它是一件考古文物。可以追溯到 .NET 之前和委托(delegate)发明之前。 CLR 最初是 Project 42 中的“通用运行时”,这是 .NET 之前的一个失败项目。

也许一些 C++/CLI 代码来演示如何生成一个是有用的,向您展示如何创建它:

#include "stdafx.h"

using namespace System;

typedef void (*functionPointer)(int);

ref class Example {
public:
    functionPointer* fp;
};

int main(array<System::String ^> ^args)
{
    auto field = Example::typeid->GetField("fp");
    auto name = field->FieldType->FullName; 
    Console::WriteLine(name);
    return 0;
}

输出:(fnptr)*

关于c# - 什么是 (fnptr)* 类型以及如何创建它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27195502/

相关文章:

.net - 为什么 .Net Socket.Disconnect 需要两分钟?

c# - 为什么 WCF 契约(Contract)会包含 ref/out 参数?

php - 确定用于 PHP DOTNET 的程序集名称

c# - 访问空值会导致应用程序失败/C#

c# - const 和非常量函数重载

c# - 从后台线程更新 UI

c# - NullReferenceException 未处理 - 什么是 null?

c# - .IsKeyDown(Keys keys) 不工作?

c# - 在泛型集合中使用类型变量

java - 从java文件生成JSON