Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Андрей Бушман от 28-11-2013, 08:35:00

Название: The caller must release the interface when the operation is complete.
Отправлено: Андрей Бушман от 28-11-2013, 08:35:00
Доброго времени суток.
Фрагмент текста из документации по COM API подшивок:
Цитата: acad_sso.chm
AcSmResources.GetEnumerator Method
 
Returns an enumerator of the contained IAcSmFileReference components in the collection.
The caller must release the interface when the operation is complete.
Syntax
GetEnumerator() As IAcSmEnumFileReference
В .NET под освобождением я бы понимал вызов IDisposable.Dispose(), в случае его реализации, или же присвоение null в качестве значения. В обозначенном выше фрагменте документации, как я понимаю, под "освобождением" понимается обычное присвоение null (уточняю на всякий случай)? Или же я должен вызвать какую-то функцию, присутствующую в одном из базовых интерфейсов COM? Если второй вариант, то что это за функция?

Спасибо
Название: Re: The caller must release the interface when the operation is complete.
Отправлено: Александр Ривилис от 28-11-2013, 10:04:03
Или же я должен вызвать какую-то функцию, присутствующую в одном из базовых интерфейсов COM? Если второй вариант, то что это за функция?
Не проверял, но должен быть метод Release, который и имеется в виду.
Название: Re: The caller must release the interface when the operation is complete.
Отправлено: Андрей Бушман от 28-11-2013, 10:28:03
Не проверял, но должен быть метод Release, который и имеется в виду.
Этот метод я искал в первую очередь :)

Обозначенная вами функция присутствовала бы в том случае, если бы был реализован интерфейс IUnknown, но поскольку это сделано не было (http://forum.dwg.ru/showpost.php?p=368913&postcount=216) (IDispatch включает в себя (http://msdn.microsoft.com/en-us/library/windows/desktop/dd318520(v=vs.85).aspx) IUnknown), то в воздухе зависает немой вопрос: поскольку нет возможности вызвать Release, то как быть в этом случае и чем для меня чревато сие безобразие (предполагаю, что утечкой памяти, но может и не только этим)?

Дополнительный вопрос: поскольку не реализован IUnknown, то каким образом освобождает указанные выше ресурсы стандартный Sheet Set Manager, по умолчанию присутствующий в AutoCAD?
Название: Re: The caller must release the interface when the operation is complete.
Отправлено: Александр Ривилис от 28-11-2013, 13:06:44
Дополнительный вопрос: поскольку не реализован IUnknown, то каким образом освобождает указанные выше ресурсы стандартный Sheet Set Manager, по умолчанию присутствующий в AutoCAD?
Интерфейс IUnknown фактически используется для подсчета ссылок на COM-объект: метод AddRef добавляет единицу к счетчику ссылок, а метод Release уменьшает этот счетчик на единицу. Т.е. освобождение ресурса происходит не здесь.
Судя по тем примерам, которые имеются (пример (http://through-the-interface.typepad.com/through_the_interface/2010/05/populating-a-tree-view-inside-autocad-with-sheet-set-data-using-net-part-2.html)) - это баг в документации и ничего освобождать не нужно.
Название: Re: The caller must release the interface when the operation is complete.
Отправлено: Андрей Бушман от 28-11-2013, 13:12:04
Судя по тем примерам, которые имеются (пример) - это баг в документации и ничего освобождать не нужно.
Хотелось бы знать точно. :)
Название: Re: The caller must release the interface when the operation is complete.
Отправлено: Александр Ривилис от 28-11-2013, 13:12:56
Хорошо. Задам вопрос в ADN DevHelp.
Название: Re: The caller must release the interface when the operation is complete.
Отправлено: Андрей Бушман от 28-11-2013, 14:11:10
Хорошо. Задам вопрос в ADN DevHelp.
Спасибо!
Название: Re: The caller must release the interface when the operation is complete.
Отправлено: Александр Ривилис от 01-12-2013, 03:37:10
Получил ответ. Если в двух словах, то это требование касалось чистого COM. В .NET эту функцию берёт на себя сборщик мусора. Но если тебе необходимо немедленно освободить этот ресурс, то воспользуйся методом:
Код - C# [Выбрать]
  1. Marshal.ReleaseComObject([освобождаемый объект]);
Название: Re: The caller must release the interface when the operation is complete.
Отправлено: Андрей Бушман от 01-12-2013, 09:26:41
Спасибо.
Если в двух словах, то это требование касалось чистого COM.
Любопытно... А как это требование следовало бы выполнять, учитывая отсутстствие обозначенных мною выше интерфейсов, если бы я писал плагин, к примеру, на VBA, или на native C++?

Название: Re: The caller must release the interface when the operation is complete.
Отправлено: Александр Ривилис от 01-12-2013, 20:44:15
Кто сказал, что IUnknown не реализован в указанных тобой интерфейсах? Например, IAcSmEnumFileReference:
    interface IAcSmEnumFileReference : IUnknown {
        [helpstring("Iterates to and returns the next element."), helpcontext(0x00000001)]
        HRESULT _stdcall Next([out, retval] IAcSmFileReference** ppRef);
        [helpstring("Resets the enumerator before the first element."), helpcontext(0x00000001)]
        HRESULT _stdcall Reset();
    };
Смотри idl-файлы в аттаче. Т.е. как минимум с AutoCAD 2004 по AutoCAD 2014 интерфейс IUnknown в указанных тобой интерфейсах реализован.
Название: Re: The caller must release the interface when the operation is complete.
Отправлено: Андрей Бушман от 02-12-2013, 10:09:40
Кто сказал, что IUnknown не реализован в указанных тобой интерфейсах? Например, IAcSmEnumFileReference
Я вот что вижу в MS VS для IAcSmEnumFileReference:
Код - C# [Выбрать]
  1. namespace ACSMCOMPONENTS17Lib {
  2.         [InterfaceType(1)]
  3.         [Guid("DCC34BDE-CE4E-4A06-A74B-7EE11B8F32C5")]
  4.         public interface IAcSmEnumFileReference {
  5.                 IAcSmFileReference Next();
  6.                 void Reset();
  7.         }
  8. }
Соответственно, для экземпляра IAcSmEnumFileReference не доступны функции, определённые в составе IUnknown.

В указанном вами файле ACSMCOMPONENTS16Lib.idl для ля IAcSmEnumFileReference вижу это:
Код - C# [Выбрать]
  1.     interface IAcSmEnumFileReference : IUnknown {
  2.         [helpstring("Iterates to and returns the next element."), helpcontext(0x00000001)]
  3.         HRESULT _stdcall Next([out, retval] IAcSmFileReference** ppRef);
  4.         [helpstring("Resets the enumerator before the first element."), helpcontext(0x00000001)]
  5.         HRESULT _stdcall Reset();
  6.     };

Почему такая разница в объявлении интерфейсов?
Название: Re: The caller must release the interface when the operation is complete.
Отправлено: Александр Ривилис от 02-12-2013, 19:17:04
Разница в том, что у тебя показан преобразованный для .NET интерфейс, для которого VS создала обертку. Я же тебе показал как выглядят интерфейсы в COM (при помощи утилиты OLEView (http://msdn.microsoft.com/ru-ru/library/w9yyfff5%28v=vs.90%29.aspx), водящей в состав VS)
Кстати обрати внимание, на
[InterfaceType(1)]в твоём коде.  Класс InterfaceTypeAttribute (http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.interfacetypeattribute%28v=vs.110%29.aspx) как раз и используется для указания того, какой COM-интерфейс наследуется. И InterfaceIsIUnknown как раз и равен 1, т.е. можно читать как:
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]