C# FreeLibrary无限期返回true
FreeLibrary重复返回true有什么原因吗 我试图从进程中卸载一些本机dll,所以我得到它的句柄,然后调用FreeLibrary,直到ref计数变为零,所以FreeLibrary返回false。。。但它从来没有: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)); 代码运行并
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在进程退出之前不会卸载。来源-例如:或