以下 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/