c# - CLR 在调用程序集中的任何方法之前调用的最早入口点是什么?

标签 c# .net assemblies entry-point static-constructor

在过去的几年里,我偶尔想知道 .NET 世界中有什么等同于(著名的)DLL_PROCESS_ATTACH 的东西。我的任何文档都说,稍微简化了,类的最早入口点是静态构造函数 (cctor),但你不能影响 when it is called ,也不能定义一个保证在任何其他 cctor 或字段初始值设定项之前被调用的 cctor,hack,如果从未使用过该类,它甚至可能根本不会被调用。

因此,如果您想保证在调用程序集的任何方法之前初始化某些东西,并且您不想必须向程序集中的每个类添加一个 cctor,您可以采用什么方法拿?或者有没有一种我多年来一直错过的 .NET 中的简单托管解决方案?

最佳答案

我通常不会回答我自己的问题,但与此同时我确实找到了一个以前没有出现过的答案,所以我来了。

经过一些研究,我碰巧在 this post by Microsoft ,这解释了在内部混合托管和非托管代码的问题 DllMain以及第二版 CLI module initializers 中出现的解决方案。引用:

This initializer runs just after the native DllMain (in other words, outside of loader lock) but before any managed code is run or managed data is accessed from that module. The semantics of the module .cctor are very similar to those of class .cctors and are defined in the ECMA C# and Common Language Infrastructure Standards.

虽然我无法在当前 ECMA 规范中找到术语模块初始化器,但它在逻辑上遵循类型初始化器 和全局 <Module>特殊类别(参见第 22.26 节关于 MethodDef,子点 40)。此功能是在 .NET 1.1之后实现的(即,从 2.0 开始)。另见 this semi-official description .

这个问题不是关于 C# 的,而是因为它是 .NET 的通用语言:C# 不知道全局方法,您不能创建 <Module> ,更不用说它的cctor了。然而,Einar Egilsson 有 recognized this apparent deficiency并创建了 InjectModuleInitializer.exe,它允许您将此作为 Visual Studio 的后/编译步骤执行。在 C++.NET 中,使用此方法很简单,推荐使用此方法代替 DllMain .另见 this SO answer by Ben Voigt (不是公认的答案)和这个 SO answer by yoyoyoyosef .

简而言之,模块初始值设定项是在加载模块之后(加载程序集时不一定!)和调用任何类或实例方法之前调用的第一个方法。它不接受任何参数,不返回任何值,但可以在其主体中包含任何托管代码。

关于c# - CLR 在调用程序集中的任何方法之前调用的最早入口点是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3363569/

相关文章:

c# - 无法解析远程名称 : 'api-3t.sandbox.paypal.com'

c# - 从基础实体访问子实体的属性

.net - 强签名和更新引用程序集

.net - 在没有源代码的情况下本地化 .NET 程序集

c# - 以编程方式将强命名程序集添加到 GAC

c# - 如何提取自定义 header 值?

c# - 如何在没有作业程序集的本地副本的情况下在 Quartz.net 中安排远程作业?

c# - 让 VS 突出显示所有 .Net 3.5 SP1 方法调用

c# - 在 C# 中将 DataUrl 转换为图像并写入包含字节的文件

.net - Silverlight 3 到 4 风险分析