Csharp/C#教程:卸载使用DllImport加载的DLL分享


卸载使用DllImport加载的DLL

如何卸载在C#中使用DllImport加载的DLL?

从[DllImport] pinvoke声明加载的进程中卸载非托管DLL的最可靠方法是通过pinvoking LoadLibrary()再次自己加载它。 这为DLL提供了可靠的句柄,即使DLL的模块名称不明确,也能正常工作。 它在运行时没有任何影响,除了Windows加载器将DLL的内部引用计数从1增加到2。

然后,您可以将FreeLibrary() 两次旋转以将引用计数减少为0,并将其从LoadLibrary()传递给IntPtr。 卸载DLL,以及任何加载的依赖DLL。

请注意,当您尝试再次对DLL上的任何导出函数进行pinvoke时,您将会遇到非常严重的故障。 pinvoke marshaller不知道DLL不再存在,并且会在它认为仍然有效的地址调用该函数。 如果幸运的话,哪些程序会使用AccessViolationexception对您的程序进行轰炸。 或者运行一个完全随机的代码,如果你不是那么幸运,以前DLL占用的地址空间被另一个DLL重用。 那么一切都会发生,没有一件好事。

这应该释放先前在您调用P / Invoke函数时加载的模块。

 [DllImport("kernel32", SetLastError=true)] static extern bool FreeLibrary(IntPtr hModule); public static void UnloadModule(string moduleName) { foreach(ProcessModule mod in Process.GetCurrentProcess().Modules) { if(mod.ModuleName == moduleName) { FreeLibrary(mod.BaseAddress); } } } 

根据彼得斯的建议,这对我有用:

  [DllImport("kernel32", SetLastError = true)] private static extern bool FreeLibrary(IntPtr hModule); public static void UnloadImportedDll(string DllPath) { foreach (System.Diagnostics.ProcessModule mod in System.Diagnostics.Process.GetCurrentProcess().Modules) { if (mod.FileName == DllPath) { FreeLibrary(mod.BaseAddress); } } } 

由于我在浏览信息时遇到了这些信息,因此我想我会回过头来解决OSX IN UNITY上的Sixense SDK问题。 你会在那里看到在OSX上动态加载/卸载dylib的实现:

https://gist.github.com/amirebrahimi/d7b02c01bcd3ca7da144

如果您是函数式编程的粉丝,那么您可以使用LINQ来实现@IllidanS4建议的内容:

上述就是C#学习教程:卸载使用DllImport加载的DLL分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

 [DllImport("kernel32", SetLastError=true)] static extern bool FreeLibrary(IntPtr hModule); public static void UnloadModule(string moduleName) { var loadedAssemblyModule = Process.GetCurrentProcess().Modules.OfType() .FirstOrDefault(x => x.ModuleName == moduleName); if (loadedAssemblyModule != null) FreeLibrary(loadedAssemblyModule.BaseAddress); } 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1021591.html

(0)
上一篇 2022年1月6日
下一篇 2022年1月6日

精彩推荐