C# C语言中的隐式链接与自由库#

C# C语言中的隐式链接与自由库#,c#,dll,linker,implicit,C#,Dll,Linker,Implicit,我刚刚发现我可以卸载DLL,它是与C#中的函数FreeLibrary()隐式链接的。我记得我不能在C++中这样做,但是它在我的简单测试项目中很好。我想知道这在我真正的项目中是否也可以使用这种方法安全吗?相当模糊,我不得不假设您谈论的是通过pinvoke加载的DLL。是的,没有防止调用FreeLibrary()两次的保护措施。在C++中以及在BTW中工作,用于显式加载的DLL。不是隐式加载的DLL,它们的引用计数为“无穷大” pinvoke marshaller在第一个[DllImport]函数执

我刚刚发现我可以卸载DLL,它是与C#中的函数FreeLibrary()隐式链接的。我记得我不能在C++中这样做,但是它在我的简单测试项目中很好。我想知道这在我真正的项目中是否也可以使用这种方法安全吗?

相当模糊,我不得不假设您谈论的是通过pinvoke加载的DLL。是的,没有防止调用FreeLibrary()两次的保护措施。在C++中以及在BTW中工作,用于显式加载的DLL。不是隐式加载的DLL,它们的引用计数为“无穷大”

pinvoke marshaller在第一个[DllImport]函数执行时在引擎盖下使用LoadLibrary()。OS加载器只保留一个引用计数,每次LoadLibrary()调用都会增加该计数,而FreeLibrary()则会减少该计数。当它达到0时,它将被卸载。因此,如果您自己pinvoke LoadLibrary()并调用FreeLibrary()两次,则DLL确实会被卸载。以前由映射DLL中代码的内存映射文件使用的虚拟地址空间将被释放,并可由后续分配再次使用

安全,不,这不是一个让人想到的词。当您意外地调用DLL中的入口点时,您的程序将表现得非常糟糕。pinvoke marshaller对此无能为力,本机方法的存根已经生成。AccessViolationException发生的几率很高,但不能保证。任意代码执行在技术上是可能的


唯一真正安全的方法是确保卸载包含pinvoke代码的AppDomain。在这方面你没有得到任何帮助,只有一条规则你必须自己实施。

非常感谢你的回复。但我的意思是关于隐式链接,而你在谈论显式链接。在C++中,FRIELBRARYARY()只在与函数LoopRealSub()链接的显式链接上正常工作。另一方面,FreeLibrary()在C#中同时处理显式和隐式链接。我对此进行了多次测试,希望确保调用FreeLibrary()进行隐式链接不会在将来导致任何问题,因为我找不到任何关于此的文档。无论如何,谢谢你的建议!它没有什么不同,在C++中,仍然可以调用LoopRealAuthor()一次和FielBrror()两次来卸载隐式加载的DLL。你的问题根本不清楚DLL是如何隐式加载到C程序中的。请改进一下。请记住,.NET程序集不是由LoadLibrary或隐式链接加载的,只能通过销毁AppDealEnter来卸载,C++中的“调用LoopRealAuthor”一次和FielyBrror()两次对您起作用。我已经尝试过了,调用了FreeLibrary()十多次,但是对于使用“#pragma comment(lib,“myDLL”)加载的DLL,它不起作用。不管怎样我都要试试。在C#中,我使用DllImport属性加载自己的DLL,但问题是,这种方法无法卸载。我搜索了如何卸载,但很多人说只使用LoadLibrary()和FreeLibrary(),而不是DllImport。坦率地说,我看到一个人说在C#中调用LoadLibrary()一次和FreeLibrary()两次,就像你一样。但那只是一次,所以我不能确定仅仅因为它工作就可以使用该方法。啊,是的,你是对的,隐式加载的非托管DLL的引用计数为-1。[DllImport]DLL永远不会隐式加载,pinvoke封送器会在引擎盖下调用LoadLibrary()。