Когда и почему я использую CoTaskMemAlloc () в фильтре DirectShow? - PullRequest
2 голосов
/ 27 октября 2011

Я создаю фильтр DirectShow в Delphi 6 Pro с использованием библиотеки компонентов DSPACK DirectShow.В их примере Push Source Filter для некоторых элементов они используют CoTaskMemAlloc (), особенно с выделением памяти для элементов, используемых в вызовах Windows API, таких как заголовки информации растрового видео (PVIDEOINFOHEADER) и буферы, используемые в операциях с файлами O / S, таких как ReadFile и т. Д.. Другие элементы выделяются с помощью обычного вызова (Object) .Create () или путем непосредственного создания динамических массивов.

Каковы правила / рекомендации, когда необходимо использовать CoTaskMemAlloc () внутри фильтра DirectShow?
Этот SO-ответ @Vinay дает краткий ответ о том, что его следует использовать с любой памятью, которая пересекает границы процесса :

Использование CoTaskMemAlloc?

Но я хотел бы знать, есть ли какие-либо распространенные ошибки выделения памяти, которые я, скорее всего, совершу в своем фильтре DirectShow, особенно при рендеринге или предоставлении данных через выводы ввода / вывода, из-за моей неспособности использовать CoTaskMemAlloc ().

Ответы [ 2 ]

3 голосов
/ 27 октября 2011

CoTaskMemAlloc является частью распределителя памяти COM.Он используется с CoTaskMemRealloc и CoTaskMemFree.

Распределитель памяти COM предназначен для того, чтобы позволить клиенту COM выделять память, которая впоследствии освобождается сервером COM или наоборот.Вам нужно использовать его только тогда, когда владение памятью передается через границу COM клиент / сервер.

Это решает очень распространенную проблему взаимодействия.Разные системы программирования имеют разные реализации для куч.Следовательно, память, выделенная в одной куче, может быть освобождена только в той же куче.Если у вас есть метод COM, который возвращает строку, скажем, у вас есть проблема.Если сервер и клиент используют разные кучи, вам нужно попросить сервер освободить строку, когда вы закончите с ней.Распределитель COM решает эту проблему благодаря единой общей куче, которую могут использовать все участники.

Сказав это, неудивительно, что BSTR, то есть то, что в Delphi называется WideString, являетсявыделено с помощью COM-распределителя.

Я не знаком с интерфейсами DirectShow, но принципы COM универсальны.Когда вы реализуете GetMediaType на своем сервере, вы должны выделить возвращаемую структуру.Поскольку клиент должен освободить эту структуру, как указано в документации, очевидно, что вы должны использовать COM-распределитель, поскольку именно это будут использовать ваши клиенты.

Вы также упомянули ReadFile.Здесь вообще нет смысла использовать COM-распределитель, так как вызывающий отвечает как за выделение, так и за освобождение буфера.

Суть в том, что COM является интерфейсным контрактом.Если указатель пересекает границу интерфейса и владелец передается от клиента к серверу или наоборот, то должен использоваться распределитель COM.

1 голос
/ 27 октября 2011

Вы ДОЛЖНЫ использовать CoTaskMemAlloc для любого выделения памяти в COM, которое будет передано во внешний мир. Фильтры DirectShow используют COM и передают буферы из фильтра в фильтр, чтобы избежать копирования данных.

...