今天我重新阅读一些 .Net 文档时,我注意到该文档的第一部分extern关键词文档 https://msdn.microsoft.com/en-us/library/e59b22c5.aspx claims:
extern 修饰符用于声明外部实现的方法。常见用途当您使用互操作服务调用非托管代码时,extern 修饰符与 DllImport 属性一起使用。
引起我注意的是该文件指出“常见用途”extern
是它与 DllImport 属性一起使用。这意味着还有其他不需要 DllImport 的用例。我不必将许多外部非托管库集成到我的应用程序中,但在所有情况下链接的方法都是使用 DllImport 定义的。
我通过 Google 和 MSDN 搜索了多个查询,但找不到案例或解释extern
将使用关键字而不将方法定义为从非托管 dll 导入的外部方法。
您将如何以及何时使用extern
没有定义关键字[DllImport(...)]
方法定义上的属性?
请注意,这并不特定于使用extern
定义别名时。这是关键字的不同用法,这种情况是在另一篇文章中概述 https://msdn.microsoft.com/en-us/library/ms173212.aspxMSDN C# 语言参考中。
我使用它的一种情况是,如果我是一名 Microsoft 开发人员,正在实现对 CLR 本身中定义的方法的调用。像GC._WaitForFullGCApproach
:
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern int _WaitForFullGCApproach(int millisecondsTimeout);
注:无DllImport
。当然,这有点作弊——这仍然是对非托管方法的调用,只是没有显式引用 DLL。不过,凡人无法调用此类代码,因为它仅在mscorlib
集会。
另一个应用InternalCall
位于为 COM 生成的互操作类型中:
namespace Microsoft.Office.Interop.Excel {
[DefaultMember("_Default")]
[ClassInterface(0)]
[ComSourceInterfaces("Microsoft.Office.Interop.Excel.AppEvents\0")]
[Guid("00024500-0000-0000-C000-000000000046")]
[TypeLibType(2)]
[ComImport]
public class ApplicationClass {
// ...
[DispId(302)]
[MethodImpl(MethodImplOptions.InternalCall)]
public virtual extern void Quit();
// ...
}
}
这些属性允许运行时将方法调用解析为对 COM 接口的调用。这种使用InternalCall
is外部有效mscorlib
, 明显地。您通常不会自己用 C# 编写此类代码;当您添加 COM 类型库作为引用时,它会根据需要生成。
C# 语言规范比 MSDN 更详细:
The extern
修饰符通常与DllImport
属性(§17.5.1),允许外部方法由
DLL(动态链接库)。执行环境可能支持
可以通过其他机制实现外部方法
假如。
从实现的角度来看,标记一个方法extern
仅仅具有将方法的RVA(相对虚拟地址)设置为0的效果,将其标记为没有实现。属性如DllImport
(and MethodImpl
)对于向运行时描述如何定位方法的实际实现是必要的。 ECMA-335 的 I.9.4 节“方法实现元数据”对此进行了描述(以及DllImport
and InternalCall
似乎是目前唯一可用的方法)。
C# 编译器将允许您将方法标记为extern
and not使用任何属性来指示实现所在的位置,但是任何具有此类方法的类型都将导致TypeLoadException
在运行时。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)