我刚接触C++/CLI,请多包涵...
我正在开发一个混合的C++/CLI DLL,它应该作为Win32进程和.NET程序集之间的桥梁。在DLL中,我需要在整个DLL生命周期内存在一些.NET内容。初始化不是太大的问题,但我无法弄清楚何时可以安全地清理.NET内容。通常的C++工具(DLL_PROCESS_DETACH、全局变量和静态本地析构函数)似乎都在CLR消失后被调用。
那么,有什么方法可以通知DLL即将从CLR分离,这样我就可以释放我所持有的.NET引用了吗?
回答自己的问题似乎有些尴尬,但是没有其他人提出这个建议,而且这正是我想要的……所以:
原来微软提供了一个名为_onexit_m的奇特变体,应该在混合模式DLL中使用。当使用_onexit_m来注册(托管)回调函数时,该函数将在DLL即将被卸载但CLR尚未关闭时调用。它类似于AppDomain.DomainUnload,由Ben Voigt建议,但由于某种原因我无法使DomainUnload工作,而IMHO使用_onexit_m更简单。
这可能不适用于 .NET 的 C++ 部分,但据我所知,让 CLR 释放已加载的程序集的唯一方法是处理 AppDomain;而且,除非您在手动管理 AppDomain 方面进行了工程化,否则您可能只有最初的 AppDomain——使处理相当于杀死应用程序。
.NET Dll 应被视为一组独立的 ref 类。每个 ref 类实例都有自己的生命周期,资源管理相对于类实例生命周期进行。正确实现 Dispose 模式可以解决所有资源管理问题。
每个具有本地资源或可释放类成员的 C++/CLI 类都应该有析构函数和可选终结器。具体来说,.NET 引用在类析构函数中释放,该函数映射到 C# 的 Dispose 方法。
GCHandle.Alloc来防止对象被回收。资源将持续到匹配的GCHandle.Free调用或应用程序域卸载。 - Ben Voigt