2012-01-20 5 views
0

Мне было интересно, стандартная практика в библиотеках COM вызывает вызов Addref на COM-интерфейсе, который возвращается из функции. Например:MSXML get_documentElement() & возвращающие указатели на COM-интерфейсы

IXMLDOMElement* domElement = NULL; 
document_->get_documentElement(&domElement); // does get_documentElement() call Addref on domElement? 
// ... 
// do something with domElement 
// .. 
domElement.Release(); // correct? 
// (btw. member variable document_ is of type CComPtr<IXMLDOMDocument2> 

или с помощью смарт-указатель:

CComPtr<IXMLDOMElement> domElement; 
document_->get_documentElement(&domElement); 

Btw. Я обнаружил, что в документации по MSXML для «СМИ для Windows 9 серии» он говорит, что AddRef называется: http://msdn.microsoft.com/en-us/library/ms751196(v=vs.85).aspx

Но в официальной документации ничего не говорится об этом: http://msdn.microsoft.com/en-us/library/ms759095(v=vs.85).aspx

ответ

2

Да вы должны AddRef перед возвратом COM-объекта, поскольку вызывающий объект будет иметь новый указатель интерфейса, ссылающийся на объект, поэтому счетчик ссылок должен быть увеличен на единицу. Это правило, а не исключение.

Документирование внутреннего addref является исключением, однако, поскольку подсчет ссылок является одной из основ COM. Вероятно, документация была написана, когда многие абоненты этого метода не знают правила и вызвали слишком много утечек памяти.

Если вы, как вызывающий, больше не нуждаетесь в полученном объекте, вам нужно вызвать Release прямо или косвенно (например, через деструктор класса) и прекратить использование указателя ссылки (многие люди устанавливают указатель на нуль, чтобы предотвратить висячие указатели).

2

Функция, возвращающая указатель интерфейса, должна вызывать AddRef() на ней перед выходом, а не на функцию, получающую объект. Функция, которая получает указатель интерфейса, должна использовать его как есть, а затем называть Release(). Это означает, что get_documentElement() вызовет AddRef(), поэтому не называйте это самим.

Правило, которые - вызывающий абонент или вызываемый абонент - отвечает за то, что в отношении к подсчету ссылок и управлению памятью в COM четко определены в документации COM на MSDN:

The Rules of the Component Object Model

Reference Counting Rules

 Смежные вопросы

  • Нет связанных вопросов^_^