PInvoke字段实现

时间:2015-06-03 12:53:27

标签: c# .net pinvoke

所以今天我浏览了ILSpy,以便更好地了解.NET如何在外部方法上执行DllImports,当我遇到奇怪的事情时:

在搜索PInvokeImpl枚举中定义的枚举值System.Reflection.MethodAttributes的引用时,我注意到System.Reflection.FieldAttributes中的匹配定义。

可以肯定的是,这似乎不仅仅是幕后重用枚举值:System.Reflection.FieldInfo有一个名为IsPinvokeImpl的公开定义的属性,它专门检查是否存在实现标志已设置。

有趣的是,MethodInfo类甚至没有此属性 - 必须从MethodImplementationFlags属性确定。

问题:

字段实际上是否可以实现PInvoke,或者这只是.NET框架中的存根实现,以实现字段装饰和方法装饰之间的平衡?

如果可能,可以在C#中完成,还是这个需要C ++ / CLI的功能?

2 个答案:

答案 0 :(得分:6)

当您查看FieldAttributes的MSDN描述时,您会看到它记录为“保留供将来使用”。那个未来还没有到来,所以它的意图没有被确定下来。

FieldAttributes之类的类型不是任意的,它们遵循CLI规范。 Ecma-335指出.NET程序集中的元数据需要看起来如何以及如何解释它。这份文件确实揭示了一个有趣的怪癖。

第II.16.1章描述了字段属性,您将看到元数据标记与FieldAttributes枚举之间的紧密匹配。但请注意,该章中pinvokeimpl 缺少

第II.2.2.1.5节给出了属性的具体值,它具有值为0x2000的PInvokeImpl。描述是“通过PInvoke转发实现”。与II.23.1.10比较,描述了方法属性。它与字段属性有许多共同的值。

这看起来很像复制/粘贴错误:))

通过.NET Framework源代码深入挖掘,CLR和抖动只考虑方法上的pinvokeimpl。但是,C#编译器似乎基于CLI规范并实际设置了该属性。出现在emit.cpp,RegMeta :: _ DefinePinvokeMap()函数中,如果为字段而不是方法调用此函数,它将设置该属性。这实际上从未发生过。

答案 1 :(得分:3)

来自FieldAttributes

  

PinvokeImpl保留供将来使用。

所以我会说:

问:字段实际上是否可以实现PInvoke

答:没有