Сущность технологии COM



         

Указатели и память - часть 8


Однако не обсуждалось, что происходит, когда объект и клиент размещаются в различных адресных пространствах. Это во многом связано с отсутствием различия в способах реализации клиентов и объектов при использовании интерфейсных маршалеров. СОМ-распределитель памяти задачи получает свою память из закрытого адресного пространства процессов. С учетом этого сокрытие того обстоятельства, что распределитель памяти задачи не может охватить оба адресных пространства, является делом интерфейсной заглушки и интерфейсного заместителя. Когда интерфейсная заглушка вызывает метод объекта, она маршалирует любые [out]- или [in, out]-параметры в ответное ORPC-сообщение. Как показано на рис. 7.1, по завершении этого маршалинга интерфейсная заглушка (которая в конечном счете является внутриапартаментным клиентом данного объекта) освобождает с помощью метода CoTaskMemFree любую память, выделенную вызываемой программой. Это эффективно освобождает всю память, выделенную в течение вызова метода внутри адресного пространства объекта. При получении ответного ORPC-сообщения интерфейсный заместитель с помощью метода CoTaskMemAlloc выделяет пространство для всех параметров, размещаемых в вызываемой программе.

Рис. 7.1. Использование распределителя памяти задачи между процессами

Когда эти блоки памяти освобождаются настоящим клиентом с помощью CoTaskMemFree, это эффективно освобождает всю память, выделенную в результате вызова метода, внутри адресного пространства клиента.

Поскольку программисты печально известны своим пренебрежением к освобождению памяти, иногда бывает полезно следить за активностью распределителя памяти задачи в процессе (или отсутствием таковой активности). Для обеспечения этого контроля СОМ предлагает подключить к распределителю памяти задачи определяемый пользователем шпионский объект (spy object), который будет уведомляться до и после каждого вызова распределителя памяти. Этот шпионский объект, определяемый пользователем, должен реализовать интерфейс IMallocSpy:

[ uuid(0000001d-0000-0000-C000-000000000046),local,object ] interface IMallocSpy : IUnknown { ULONG PreAlloc([in] ULONG cbRequest); void *PostAlloc([in] void *pActual); void *PreFree([in] void *pRequest,[in] BOOL fSpyed); void PostFree([in] BOOL fSpyed); ULONG PreRealloc([in] void *pRequest,[in] ULONG cbRequest, [out] void **ppNewRequest,[in] BOOL fSpyed); void *PostRealloc([in] void *pActual, [in] BOOL fSpyed); void *PreGetSize([in] void *pRequest, [in] BOOL fSpyed); ULONG PostGetSize([in] ULONG cbActual,[in] BOOL fSpyed); void *PreDidAlloc([in] void *pRequest, [in] BOOL fSpyed); int PostDidAlloc([in] void *pRequest, [in] BOOL fSpyed, [in] int fActual); void PreHeapMinimize(void); void PostHeapMinimize(void); }




Содержание  Назад  Вперед