为什么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源码。但是如果有任何具体的提示我应该寻找什么 - 我会很感激那些
答案 0 :(得分:1)
为什么FreeLibrary会重复返回true?
正如我已经编辑过的那样,原因很简单: