【发布时间】:2015-01-27 12:24:28
【问题描述】:
以下 IL 代码创建一个名为 (fnptr)* 的 Type 实例(令牌 0x2000000 - 无效,模块 mscorlib.dll)。
ldtoken method void* ()*
call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
这种类型的目的是什么?是否可以在不编写任何 IL 代码的情况下在 C# 中创建这种类型实例,也许使用反射?令牌上的 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; } } }
所以看起来他们忘记修复它了。
【问题讨论】:
-
有趣。你是怎么知道的?从 C++/CLI 生成的代码?
-
@leppie 是的,我只是想看看 ildasm 中的 C++/CLI 程序集,并在那里看到了
*()*。这引起了我的注意,所以我创建了上面的代码。
标签: c# .net reflection clr cil