Ill*_*ack 12 .net c# reflection clr cil
以下IL代码创建一个名为(fnptr)*(标记0x2000000 - 无效,模块mscorlib.dll)的Type实例.
ldtoken method void* ()*
call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
Run Code Online (Sandbox Code Playgroud)
这种类型的目的是什么?是否可以在C#中创建此类型实例而无需编写任何IL代码,也许可以使用反射?令牌上的Module.ResolveType抛出ArgumentOutOfRangeException.
编辑:
很明显,(fnptr)类型是IL方法指针类型的内部CLR类型表示,但是当删除最后一个时*,它只是返回IntPtr.
编辑#2:
将(fnptr)来自可在可见的功能SSCLI typestring.cpp:
Run Code Online (Sandbox Code Playgroud)// ...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中看到:
Run Code Online (Sandbox Code Playgroud)OBJECTREF TypeHandle::GetManagedClassObject() const {[...]
Run Code Online (Sandbox Code Playgroud)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之前和代表们发明之前的时间.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;
}
Run Code Online (Sandbox Code Playgroud)
输出: (fnptr)*
可以将指针的签名加载到函数指针:
public static unsafe Type GetTypeFromFieldSignature(byte[] signature, Type declaringType = null)
{
declaringType = declaringType ?? typeof(object);
Type sigtype = typeof(Type).Module.GetType("System.Signature");
Type rtype = typeof(Type).Module.GetType("System.RuntimeType");
var ctor = sigtype.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new[]{typeof(void*), typeof(int), rtype}, null);
fixed(byte* ptr = signature)
{
object sigobj = ctor.Invoke(new object[]{(IntPtr)ptr, signature.Length, declaringType});
return (Type)sigtype.InvokeMember("FieldType", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, sigobj, null);
}
}
var fnptrPtr = GetTypeFromFieldSignature(new byte[]{6, 15, 27, 0, 0, 1});
Run Code Online (Sandbox Code Playgroud)
6 是字段,15 是指针,27 是函数指针,0、0、1 是不带返回值或参数的方法签名。
| 归档时间: |
|
| 查看次数: |
1009 次 |
| 最近记录: |