Управление памятью для компонентов .NET, используемых неуправляемым кодом
-
08-07-2019 - |
Вопрос
Работая в неуправляемом мире, мы должны убедиться, что мы убираем за собой, если мы выделили память в куче (например, используя ключевое слово new
в C ++); мы также должны убедиться, что мы AddRef
COM-компоненты, которые созданы с использованием CreateInstance
и Release
позже; возможно что-то вроде:
SomeNameSapce::IObjPtr obj;
HRESULT hr = obj.CreateInstance(L"SomeObject");
if (hr == S_OK)
{
obj->AddRef();
m_anotherObj= obj->GetObj();
obj->Release();
}
Очевидно, что мы могли бы использовать умные указатели и другие подобные вещи (в C ++), но это не главное ...
Нужно ли AddRef / Release
для объектов, которые извлекаются из компонентов COM (например, m_anotherObj в приведенном выше примере)?
Чтобы сделать вещи более запутанными, что произойдет, если этот конкретный компонент, который на самом деле является компонентом .NET, подвергается воздействию неуправляемого кода через интерфейс COM? Знает ли сборщик мусора, чтобы убрать вещи или все это нужно делать вручную в неуправляемом мире?
Решение
CreateInstance
вернет вам объект со счетчиком ссылок 1, поэтому вам не нужно AddRef
его. (Умный указатель, который вы использовали, будет Release
объекта, когда он будет уничтожен.) Аналогично, объекты, которые вы получаете от методов, должны иметь счетчик ссылок уже увеличенным, поэтому вам не нужно AddRef
их снова, но вам нужно освободить
их, если вы не используете умный указатель.
COM-компоненты, предоставляемые .NET, ничем не отличаются от COM-компонентов, написанных любой другой технологией. Сборщик мусора не будет собирать объекты .NET, на которые ссылаются ссылки COM.