【发布时间】:2015-02-14 04:28:55
【问题描述】:
我真的不确定 .net dll 是否也有像 c++ dll 通常有的入口点。 如何查看 .net dll 是否有入口点。
我在某处读到 WIN32 dll 可以有入口点,点网类库没有。
谢谢,
【问题讨论】:
-
使用静态构造函数。
我真的不确定 .net dll 是否也有像 c++ dll 通常有的入口点。 如何查看 .net dll 是否有入口点。
我在某处读到 WIN32 dll 可以有入口点,点网类库没有。
谢谢,
【问题讨论】:
这是一个晦涩难懂的主题,我会以惊人的速度完成它。每个 .NET 程序集都有一个 unmanaged 入口点,5 个字节的机器代码(如果为 x64 构建,则为 9 个字节)用作 PE32 可执行文件头中标记的入口点。只有一条 JMP 指令,一个 EXE 跳转到 _CorExeMain(),一个 DLL 跳转到 _CorDllMain()。这些函数位于 mscoree.dll 中,并确保 CLR 已加载和初始化,以便它可以执行托管代码。
这些入口点有助于运行托管程序,而无需显式启动 VM 主机。避免需要mono.exe 或java.exe。它们实际上不再在现代 Windows 版本上使用,操作系统知道包含 .NET 清单的可执行文件,并且加载程序再次将作业传递给加载程序 shim,mscoree.dll。这种意识对于实现considerable trick 建立一个包含 32 位 PE32 标头的 EXE 的 64 位进程是必要的。 Mscoree.dll 修补内部加载程序数据结构来完成这一壮举。
每个 .NET 程序集还包含一个 托管 入口点,在清单标头中列出。由 CLR 在加载程序集后立即调用。一个 EXE 总是有一个,它指向 Main() 方法,编译器确保你不会忘记写一个。一个 DLL 可能有一个,例如,混合模式程序集总是有一个。指向位于<Module> 类中的module initializer,C++/CLI 编译器使用它来确保在任何托管代码可以执行之前初始化 CRT(C 运行时库)。
【讨论】:
不,.NET DLL 程序集没有DllMain,就像非托管 DLL 那样。但是,在DllMain 中实现的所有行为通常都可以使用各种 .NET 结构来实现。例如:
IDisposable 接口可为您提供确定性清理。实现终结器为您提供了非确定性清理的可能性(但不是保证)(即在对象被垃圾收集之前)AppDomain 具有 DomainUnload 和 ProcessExit 事件,可让您在应用域或进程关闭时运行清理代码。【讨论】:
DllMain() 形成对比,它是 C/C++ 代码中的标准构造)。