#delphi #directshow #smart-pointers #dspack
#delphi #directshow #интеллектуальные указатели #dspack
Вопрос:
У меня только что был длительный сеанс отладки, который был вызван «устаревшей» ссылкой на интерфейс в моем приложении DirectShow на Delphi 6, использующем библиотеку компонентов DSPACK. Как вы знаете, есть некоторые операции, которые необходимо выполнить, когда график фильтров активен, и другие, которые выполняются с параметрами компонента, когда график фильтров должен быть неактивным. Проблема в том, что в конечном итоге вы можете получить ссылки на интерфейс DirectShow, которые все еще имеют инициализированные значения (присвоенные, а не NIL), но недействительны для текущего воплощения графика фильтров, поскольку они были созданы во время предыдущего воплощения графика фильтров. Это не так уж сложно сделать случайно, когда вы включаете и выключаете график фильтров для переключения между операциями обнаружения «в реальном времени» и операциями настройки в автономном режиме. Примером автономной работы является установка псевдонима для одного из компонентов DSPACK, который будет использоваться при создании экземпляра конкретного фильтра при следующем включении графика.
Например, у вас может быть ссылка на IBaseFilter, которую вы назначили при первой активации графика фильтров, которую вы пытались повторно использовать после деактивации и повторной активации графика фильтров. Ссылка на интерфейс теперь «устаревшая», потому что она принадлежит не текущему воплощению графа фильтров, а предыдущему. Это приводит ко всевозможным странным и неинтуитивным сообщениям об ошибках DirectShow, которые не являются тем, чем кажутся, но на самом деле вызваны устареванием ссылки на интерфейс.
Кто-нибудь придумал способ, будь то по соглашению или с помощью какого-нибудь умного решения, такого как интеллектуальный указатель DirectShow, привязанный к времени жизни графика фильтров и т.д., Чтобы предотвратить это? Или это единственное решение, позволяющее проявлять неустанную осторожность при использовании ссылок на интерфейс?
Ответ №1:
Как разработчик фильтра вы возвращаете коды ошибок, когда фильтр получает некоторый запрос на обработку и оказывается, что фильтр уже был удален из graph или изменил свое состояние.
Со стороны приложения вы можете реализовать любой вид синхронизации, указывающий на завершение работы. Например, перед остановкой / выпуском графика фильтрации вы можете установить флаг завершения (логическую переменную), и при своего рода обратном вызове обработки, который может запаздывать и требовать синхронизации, вы проверяете флаг и знаете, когда пришло время прервать обработку из-за невыполненного запроса на завершение.