FreeLibrary无限期地返回true

有没有理由说FreeLibrary会重复返回true?

我正试图从我的进程中卸载一些本机dll,所以我得到它的句柄,然后调用FreeLibrary直到引用计数变为零,因此FreeLibrary返回false …但它永远不会:

IntPtr pDll = DllLoadingImports.LoadLibrary(dllTounLoad); //throw if pDll == IntPtr.Zero while(DllLoadingImports.FreeLibrary(pDll)); 

代码运行,永不返回。 进程资源管理器也会显示仍然加载的dll。

更多背景:

我正在尝试卸载使用DllImport加载的本机库,我正在使用这里描述的技巧: https ://stackoverflow.com/a/2445558/2308106这是为了进行原型设计,所以我不必关心可能的结果…但我很困惑为什么图书馆不会卸载

编辑1 :我发现通过在GetModuleHandleEx函数中指定GET_MODULE_HANDLE_EX_FLAG_PIN标志可以实现类似的行为(可以在dll加载时从DllMain中调用)。

我试图卸载的DLL是python.dll(更准确地说是python36.dll)。 但是在python源代码中没有找到这个标志的用法。 DllMain本身是空的。

编辑2 :我被问到最小的可执行示例 – 所以这里它:它使用pythonnet库(版本2.3.0) – 这是PythonEngine调用。

 [TestFixture] public class PythonUnloadTest { public static class DllImports { [DllImport("kernel32.dll")] public static extern IntPtr LoadLibrary(string dllToLoad); [DllImport("kernel32.dll")] public static extern bool FreeLibrary(IntPtr hModule); } [Test] public void PythonLoadUnload() { const string PythonDll = @"PythonEngine\python36"; PythonEngine.Initialize(); //locking etc not included for simplicity //Replace module with 'sys' (or some others) and dll can be unloaded var module = PythonEngine.ImportModule("numpy"); module.Dispose(); IntPtr pythonDllHandle = DllImports.LoadLibrary(PythonDll); if (pythonDllHandle == IntPtr.Zero) { throw new Exception("Dll not loaded"); } for (int i = 0; i < 100000; i++) { if (!DllImports.FreeLibrary(pythonDllHandle)) { return; } } Assert.Fail("Python not unloaded"); } } 

无论这种具体情况如何 (python和pythonnet以及numpy的加载) – 仍然需要一些现象来阻止进程通过调用FreeLibrary来卸载dll。 我怀疑安装一些钩子或用上面提到的标志调用GetModuleHandleEx ……我会尝试检查numpy源码。 但如果有任何具体的提示我应该寻找什么 – 我会很感激

有没有理由说FreeLibrary会重复返回true?

正如我已经编辑过的那样 – 原因很少:

  • 在GetModuleHandleEx函数中指定GET_MODULE_HANDLE_EX_FLAG_PIN标志。 模块甚至可以在它的DllMain中调用它 – 渲染自我卸载。
  • 安装挂钩。 安装挂钩的模块M将不会被卸载,直到进程退出。 来源 – 例如: https : //msdn.microsoft.com/en-us/library/ms644960 ( v = VS.85).aspx# system_events或https://blogs.msmvps.com/vandooren/2006/10/09 /防止-A-DLL-从感卸载的由这-APP-该用途-它/