我通常不会回答我自己的问题,但同时我确实找到了一个以前没有出现过的答案,所以我开始了。
经过一番研究,我偶然看到了Microsoft 的这篇文章,它解释了在内部混合托管和非托管代码的问题DllMain
以及解决方案,该解决方案来自 CLI 的第二个版本,模块初始化程序。引用:
此初始化程序在本机 DllMain 之后(换句话说,在加载程序锁定之外)运行,但在运行任何托管代码或从该模块访问托管数据之前。模块 .cctor 的语义与类 .cctor 的语义非常相似,并且在 ECMA C# 和通用语言基础设施标准中定义。
虽然我无法在当前的 ECMA 规范中找到术语模块初始化器,但它在逻辑上遵循类型初始化器和全局<Module>
特殊类(参见第 22.26 节关于 MethodDef 的第 40 小点)。此功能是在.NET 1.1 之后实现的(即从 2.0 开始)。另请参阅此半官方描述。
这个问题不是关于 C#,而是因为它是 .NET 的通用语言:C# 不知道全局方法,你不能创建一个<Module>
,更不用说它的 cctor 了。但是,Einar Egilsson 已经认识到这一明显的缺陷并创建了 InjectModuleInitializer.exe,它允许您在 Visual Studio 的后/编译步骤中执行此操作。在 C++.NET 中,使用这种方法是微不足道的,推荐的做法是代替DllMain
. 另请参阅Ben Voigt 的这个 SO 答案(不是公认的答案)和yoyoyoyosef 的这个 SO 答案。
简而言之,模块初始化程序是在加载模块之后(不一定是在加载程序集时!)调用任何类或实例方法之前调用的第一个方法。它不接受参数,不返回任何值,但可以在其主体中包含任何托管代码。