当c++ /CLI DLL卸载时,如何清除。net内容?

时间:2022-09-01 13:43:57

I'm new to C++/CLI, so please bear with me...

我是c++ /CLI的新手,请耐心等待……

I'm working on a mixed C++/CLI DLL, which should act as a bridge between a Win32 process and a .NET assembly. In the DLL, I need some .NET stuff to be present during the lifespan of the DLL. Initializing is not that big a problem, but I couldn't figure out when can I safely cleanup the .NET stuff. The usual C++ facilities (DLL_PROCESS_DETACH, global variables and static locals d'tors) all seem to be called after the CLR has gone away.

我正在编写一个混合c++ /CLI DLL,它应该充当Win32进程和. net程序集之间的桥梁。在DLL中,我需要一些。net的东西在DLL的生命周期中出现。初始化并不是什么大问题,但是我不知道什么时候可以安全地清除。net的内容。通常的c++工具(DLL_PROCESS_DETACH、全局变量和静态局部变量d'tors)似乎都是在CLR消失后调用的。

So, what is the way to get notified the DLL is about to detach from the CLR, so I can release the .NET references I hold?

那么,如何获得通知DLL将从CLR中分离,这样我就可以释放我所持有的.NET引用了?

4 个解决方案

#1


2  

If you need to take care of AppDomain unloads, use the AppDomain.DomainUnload event to do your cleanup.

如果需要处理AppDomain卸载,请使用AppDomain。DomainUnload事件来进行清理。

As STW says, libraries with managed code can never be detached from an AppDomain, the only way to detach it from your process is to unload the AppDomain.

正如STW所言,具有托管代码的库永远无法与AppDomain分离,将其与进程分离的唯一方法是卸载AppDomain。

If you aren't managing AppDomains, just leak the managed resource (and properly flush unmanaged resources during process detach). Better yet, design it as crash-only software so that no cleanup is required.

如果您没有管理AppDomains,那么只泄漏托管资源(并在进程分离过程中正确地冲洗非托管资源)。更好的是,将其设计为只使用crashonly的软件,这样就不需要进行任何清理。

#2


2  

Well, answering my own question seems awkward, but this wasn't suggested by anyone else, and it is what I was looking for... so:

嗯,回答我自己的问题似乎有些尴尬,但这不是别人建议的,这是我要找的……所以:

turns out Microsoft offers an exotic variation of onexit, called _onexit_m, which should be used in mixed-mode DLLs. When using _onexit_m to register a (managed) callback function, that function will be called when the DLL is about to be unloaded, but before the CLR has been shut down. It is similar to AppDomain.DomainUnload, suggested by Ben Voigt, but for some reason I couldn't get DomainUnload to work, and _onexit_m is simpler to use IMHO.

事实证明,微软提供了一种奇特的onexit变体,名为_onexit_m,应该在混合模式dll中使用。当使用_onexit_m注册(托管)回调函数时,该函数将在即将卸载DLL时被调用,但在CLR被关闭之前。它类似于AppDomain。DomainUnload, Ben Voigt建议,但是出于某种原因,我无法让DomainUnload工作,而且使用IMHO更简单。

#3


0  

This might not apply to the C++ side of .NET, but to my knowledge the only way to get the CLR to release a loaded assembly is to dispose of the AppDomain; and unless you've engineered in manual AppDomain management you likely only have the initial AppDomain--making disposal the equivalent of killing your application.

这可能不适用于。net的c++方面,但据我所知,让CLR释放加载程序集的唯一方法是处理AppDomain;而且,除非您已经在手动AppDomain management中进行了设计,否则您可能只有初始的AppDomain—使处理等同于杀死应用程序。

#4


0  

.NET Dll should be treated as set of separate ref classes. Every instance of ref class has its own lifetime, and resource management is done relatively to the class instance lifetime. Properly implemented Dispose pattern solves all resource management problems.

. net Dll应该被视为一组独立的ref类。ref类的每个实例都有自己的生命周期,资源管理相对于类实例生命周期进行。正确实现的处置模式解决了所有资源管理问题。

Every C++/CLI class, which has some native resources, or disposable class members, should have destructor and optional finalizer. Specifically, .NET references are released in the class destructor, which is mapped to C# Dispose method.

每个c++ /CLI类(具有一些本机资源或可丢弃的类成员)都应该具有析构函数和可选终结器。特别地,. net引用在类析构函数中被释放,它映射到c# Dispose方法。

#1


2  

If you need to take care of AppDomain unloads, use the AppDomain.DomainUnload event to do your cleanup.

如果需要处理AppDomain卸载,请使用AppDomain。DomainUnload事件来进行清理。

As STW says, libraries with managed code can never be detached from an AppDomain, the only way to detach it from your process is to unload the AppDomain.

正如STW所言,具有托管代码的库永远无法与AppDomain分离,将其与进程分离的唯一方法是卸载AppDomain。

If you aren't managing AppDomains, just leak the managed resource (and properly flush unmanaged resources during process detach). Better yet, design it as crash-only software so that no cleanup is required.

如果您没有管理AppDomains,那么只泄漏托管资源(并在进程分离过程中正确地冲洗非托管资源)。更好的是,将其设计为只使用crashonly的软件,这样就不需要进行任何清理。

#2


2  

Well, answering my own question seems awkward, but this wasn't suggested by anyone else, and it is what I was looking for... so:

嗯,回答我自己的问题似乎有些尴尬,但这不是别人建议的,这是我要找的……所以:

turns out Microsoft offers an exotic variation of onexit, called _onexit_m, which should be used in mixed-mode DLLs. When using _onexit_m to register a (managed) callback function, that function will be called when the DLL is about to be unloaded, but before the CLR has been shut down. It is similar to AppDomain.DomainUnload, suggested by Ben Voigt, but for some reason I couldn't get DomainUnload to work, and _onexit_m is simpler to use IMHO.

事实证明,微软提供了一种奇特的onexit变体,名为_onexit_m,应该在混合模式dll中使用。当使用_onexit_m注册(托管)回调函数时,该函数将在即将卸载DLL时被调用,但在CLR被关闭之前。它类似于AppDomain。DomainUnload, Ben Voigt建议,但是出于某种原因,我无法让DomainUnload工作,而且使用IMHO更简单。

#3


0  

This might not apply to the C++ side of .NET, but to my knowledge the only way to get the CLR to release a loaded assembly is to dispose of the AppDomain; and unless you've engineered in manual AppDomain management you likely only have the initial AppDomain--making disposal the equivalent of killing your application.

这可能不适用于。net的c++方面,但据我所知,让CLR释放加载程序集的唯一方法是处理AppDomain;而且,除非您已经在手动AppDomain management中进行了设计,否则您可能只有初始的AppDomain—使处理等同于杀死应用程序。

#4


0  

.NET Dll should be treated as set of separate ref classes. Every instance of ref class has its own lifetime, and resource management is done relatively to the class instance lifetime. Properly implemented Dispose pattern solves all resource management problems.

. net Dll应该被视为一组独立的ref类。ref类的每个实例都有自己的生命周期,资源管理相对于类实例生命周期进行。正确实现的处置模式解决了所有资源管理问题。

Every C++/CLI class, which has some native resources, or disposable class members, should have destructor and optional finalizer. Specifically, .NET references are released in the class destructor, which is mapped to C# Dispose method.

每个c++ /CLI类(具有一些本机资源或可丢弃的类成员)都应该具有析构函数和可选终结器。特别地,. net引用在类析构函数中被释放,它映射到c# Dispose方法。