C# 中的隐式链接和 FreeLibrary

Implicit Linking and FreeLibrary in C#

我刚刚发现我可以卸载与 C# 中的函数 FreeLibrary() 隐式链接的 DLL。我记得我不能用 C++ 做到这一点,但它在我的简单测试项目中运行良好。我想知道这在我的实际项目中是否也可以。 使用这种方法安全吗?

相当模糊,我不得不假设您谈论的是通过 pinvoke 加载的 DLL。是的,没有防止两次调用 FreeLibrary() 的保护措施。在 C++ 中也适用于显式加载的 DLL。不适用于隐式加载的 DLL,它们的引用计数为 "infinity".

pinvoke 编组器在后台使用 LoadLibrary(),发生在第一个 [DllImport] 函数被执行时。 OS 加载器只保留一个引用计数,每次 LoadLibrary() 调用都会增加它,而 FreeLibrary() 会减少。当它达到 0 时,它就会被卸载。因此,如果您自己调用 LoadLibrary() 并调用 FreeLibrary() 两次,那么 DLL 被卸载。之前映射DLL中代码的内存映射文件使用的虚拟地址space被释放,可以被后续分配再次使用。

安全,不,这不是跳到脑海中的词。当您不小心调用 DLL 中的入口点时,您的程序将表现得很差。 pinvoke 编组器对此无能为力,本机方法的存根已经生成。出现 AccessViolationException 的几率不错,但不能保证。任意代码执行在技术上是可行的。

唯一真正安全的方法是确保卸载包含 pinvoke 代码的 AppDomain。您对此没有任何帮助,只是您必须自己实施的规则。