C# FreeLibrary无限期返回true

C# FreeLibrary无限期返回true,c#,pinvoke,dllimport,loadlibrary,python.net,C#,Pinvoke,Dllimport,Loadlibrary,Python.net,FreeLibrary重复返回true有什么原因吗 我试图从进程中卸载一些本机dll,所以我得到它的句柄,然后调用FreeLibrary,直到ref计数变为零,所以FreeLibrary返回false。。。但它从来没有: IntPtr pDll = DllLoadingImports.LoadLibrary(dllTounLoad); //throw if pDll == IntPtr.Zero while(DllLoadingImports.FreeLibrary(pDll)); 代码运行并

FreeLibrary重复返回true有什么原因吗

我试图从进程中卸载一些本机dll,所以我得到它的句柄,然后调用FreeLibrary,直到ref计数变为零,所以FreeLibrary返回false。。。但它从来没有:

IntPtr pDll = DllLoadingImports.LoadLibrary(dllTounLoad);
//throw if pDll == IntPtr.Zero
while(DllLoadingImports.FreeLibrary(pDll));
代码运行并且永远不会返回。 process explorer还会显示仍加载的dll

更多背景:

我正在尝试卸载使用DllImport加载的本机库,并使用下面介绍的技巧: 这是为了原型设计,所以我不必关心可能的冲突。。。但我不明白图书馆为什么不卸货

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

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

编辑2: 我被要求提供最低限度的可执行示例—所以这里是: 它使用pythonnet库(版本2.3.0)-这是pythonnegine调用

[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");
    }
}
[TestFixture]
公共类PythonUnloadTest
{
公共静态类DllImports
{
[DllImport(“kernel32.dll”)]
公共静态外部IntPtr加载库(字符串dlltoad);
[DllImport(“kernel32.dll”)]
公共静态外部布尔自由库(IntPtr hModule);
}
[测试]
公共空间PythonLoadUnload()
{
常量字符串PythonDll=@“PythonEngine\python36”;
PythonEngine.Initialize();
//为简单起见,不包括锁定等
//用“sys”(或其他一些)替换模块,可以卸载dll
变量模块=PythonEngine.ImportModule(“numpy”);
Dispose()模块;
IntPtr pythonDllHandle=DllImports.LoadLibrary(PythonDll);
if(pythonDllHandle==IntPtr.Zero)
{
抛出新异常(“未加载Dll”);
}
对于(int i=0;i<100000;i++)
{
如果(!DllImports.freelLibrary(pythonDllHandle))
{
返回;
}
}
Assert.Fail(“Python未卸载”);
}
}
不管这种情况如何(python和pythonnet以及numpy的加载),仍然需要一些现象来阻止进程通过调用FreeLibrary来卸载DLL。我怀疑有一些钩子,或者用上面提到的标志调用GetModuleHandleEx。。。我会检查numpy的来源。但是,如果有任何具体的提示,我应该寻找什么-我将不胜感激

FreeLibrary重复返回true有什么原因吗

正如我已经编辑过的,可能有几个原因:

  • 在函数中指定GET\u模块\u句柄\u EX\u标志\u PIN标志。模块甚至可以在它的DllMain-rendering self-unloadable中自己调用它
  • 安装挂钩。安装钩子的模块M在进程退出之前不会卸载。来源-例如:或

可能您的代码错误,但您没有显示it@DavidHeffernan代码就这么简单-这就是为什么我如此困惑的原因。它要么在LoadLibrary上失败,要么最终在FreeLibrary上返回false。。。。好吧,这些都没有发生我们看不到你的代码。你没有表现出来。也许您调用的函数只返回true。你没有表现出来。仍然没有完成。你为什么不能提供一份工作?你跟踪链接了吗?说到这里,根据我的经验,卸载和重新加载Python是无法实现的。您需要进程隔离。@DavidHeffernan您能详细说明一下“根据我的经验,卸载和重新加载Python是无法实现的”吗?这正是我要找的信息。即使在执行了一些非常简单的脚本之后,我也能够卸载和重新加载它。。然而,我在加载numpy模块后失去了这个选项