字段上的PInvoke实现
本文关键字:实现 PInvoke 字段 | 更新日期: 2023-09-27 17:53:07
所以今天我正在浏览ILSpy,以便更好地理解。net如何在外部方法上执行DllImports,当我遇到一些奇怪的事情时:
在搜索对System.Reflection.MethodAttributes
枚举中定义的枚举值PInvokeImpl
的引用时,我注意到System.Reflection.FieldAttributes
中有一个匹配的定义。
当然,这似乎不仅仅是一个幕后,枚举值的重用:System.Reflection.FieldInfo
有一个名为IsPinvokeImpl
的公共定义属性,它专门检查是否设置了这个实现标志。
有趣的是,MethodInfo
类甚至没有这个属性——它必须从MethodImplementationFlags
属性中确定。
问题:
一个字段是否有可能被PInvoke实现,或者这只是.NET框架中用于平衡字段装饰和方法装饰的存根实现?
如果可能的话,它可以在c#中完成吗,或者这是一个需要c++/CLI的功能?
当你查看fieldatattributes的MSDN描述时,你会看到它被记录为"Reserved for future use"。这个未来还没有到来,所以它的意图还没有确定。
像fieldatattributes这样的类型不是任意的,它们遵循CLI规范。Ecma-335确定了。net程序集中的元数据应该是什么样子,以及应该如何解释它。这个文档确实揭示了一个有趣的怪癖。Chapter II.16.1描述了字段属性,你会看到元数据令牌和fieldatattributes枚举之间的紧密匹配。但是请注意,pinvokeimpl
在该章中缺少。
Chapter II.23.1.5给出了属性的具体值,它有值为0x2000的PInvokeImpl。描述为"通过PInvoke转发实现"。相对于II.23.1.10,描述了方法属性。它有许多与字段属性相同的值。
这看起来很像一个复制/粘贴错误:)
在。net框架源代码中深入挖掘,CLR和jitter只考虑对方法的pinvokeimpl。然而,c#编译器似乎是基于CLI规范的,并实际设置了该属性。出现在emit.cpp, RegMeta::_DefinePinvokeMap()函数中,如果为字段而不是方法调用此函数,则将设置该属性。
From fielattributes:
PinvokeImpl保留将来使用
所以我要说:
Q:一个字段实际上可能被PInvoke实现吗
: