FreeLibrary returns 无限期为真

FreeLibrary returns true indefinitely

FreeLibrary 会重复 return 是什么原因?

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

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

代码运行并且永远不会 returns。 进程资源管理器还显示仍在加载的 dll。

更多背景:

我正在尝试卸载使用 DllImport 加载的本机库,我正在使用此处描述的技巧: 它用于原型制作目的,所以我不必关心可能的后果......但我很困惑为什么图书馆不会卸载

编辑 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 源。但是,如果有任何具体提示,我应该寻找什么 - 我将不胜感激

Is there any reason why FreeLibrary would repetitively return true?

正如我已经进行的编辑 - 可能有以下几个原因: