Administración de memoria para componentes .NET utilizados por código no administrado
-
08-07-2019 - |
Pregunta
Cuando trabajamos en el mundo no administrado, tenemos que asegurarnos de limpiar después de nosotros mismos si hemos asignado memoria en el montón (por ejemplo, usando la palabra clave new
en C ++); también debemos asegurarnos de que AddRef
componentes COM que se crean utilizando CreateInstance
y de Release
más tarde; quizás algo como:
SomeNameSapce::IObjPtr obj;
HRESULT hr = obj.CreateInstance(L"SomeObject");
if (hr == S_OK)
{
obj->AddRef();
m_anotherObj= obj->GetObj();
obj->Release();
}
Obviamente, podríamos usar punteros inteligentes y otras cosas similares (en C ++), pero eso no viene al caso ...
¿También tenemos que AddRef / Release
para los objetos que se toman de los componentes COM (como m_anotherObj en el ejemplo anterior)?
Para hacer las cosas más confusas, ¿qué sucede si este componente en particular que en realidad es un componente .NET que está expuesto a código no administrado a través de una interfaz COM? ¿El recolector de basura sabe limpiar cosas o todo tiene que hacerse manualmente en el mundo no administrado?
Solución
CreateInstance
le devolverá un objeto con un recuento de referencia de 1, por lo que no necesita AddRef
. (El puntero inteligente que ha utilizado Release
el objeto cuando se destruye). Del mismo modo, los objetos que recibe de los métodos deben tener el recuento de referencia ya incrementado, por lo que no necesita AddRef
ellos nuevamente, pero necesita Release
, a menos que esté usando un puntero inteligente.
Los componentes COM expuestos por .NET no son diferentes de los componentes COM escritos por cualquier otra tecnología. El recolector de basura no recopilará ningún objeto .NET referenciado a partir de referencias COM.