所以今天我浏览ILSpy以更好地理解.NET如何在外部方法上执行DllImports,当我遇到奇怪的事情时:
当搜索枚举PInvokeImpl中定义的枚举值的System.Reflection.MethodAttributes引用时,我注意到了匹配的定义System.Reflection.FieldAttributes.
当然,这似乎不仅仅是幕后重用枚举值:System.Reflection.FieldInfo还有一个公开定义的属性IsPinvokeImpl,它专门检查是否设置了这个实现标志.
有趣的是,这个MethodInfo班级甚至没有这个属性 - 必须从MethodImplementationFlags酒店确定.
题:
实际上是否可以将字段实现为PInvoke,或者这只是.NET框架中的存根实现,以实现字段装饰和方法装饰之间的平衡?
如果可能,可以在C#中完成,还是这是一个需要C++/CLI的功能?
当您查看FieldAttributes的MSDN描述时,您会看到它记录为"保留供将来使用".那个未来尚未到来,所以它的意图没有被确定下来.
FieldAttributes之类的类型不是任意的,它们遵循CLI规范. Ecma-335指出.NET程序集中的元数据需要看起来是什么以及如何解释它.这份文件确实揭示了一个有趣的怪癖.
第II.16.16章描述了字段属性,您将看到元数据标记与FieldAttributes枚举之间的紧密匹配.但是,请注意pinvokeimpl是缺少在这一章.
第II.2.2.1.1节给出了属性的具体值,它具有值为0x2000的PInvokeImpl.描述是"通过PInvoke转发实现".与II.23.1.10比较,描述了方法属性.它与字段属性有许多共同之处.
这看起来很像复制/粘贴bug :)
通过.NET Framework源代码深入挖掘,CLR和抖动只考虑了方法上的pinvokeimpl.但是,C#编译器似乎基于CLI规范并实际设置了该属性.出现在emit.cpp,RegMeta :: _ DefinePinvokeMap()函数中,如果为字段而不是方法调用此函数,它将设置该属性.那实际上从未发生过.
| 归档时间: |
|
| 查看次数: |
161 次 |
| 最近记录: |