Королевство Дельфи"Knowledge itself is power"
F.Bacon
 Лицей
  
Главная
О лицее

Список семинаров

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  03:16[Войти] | [Зарегистрироваться]

Урок 16. Динамическая память в COM/DCOM

Антон Григорьев
дата публикации 19-06-2008 12:21

урок из цикла: Использование COM/DCOM в Delphi


предыдущий урок содержание семинара следующий урок

Урок 16. Динамическая память в COM/DCOM

В предыдущем уроке при обсуждении атрибутов in и out мы упоминали о том что клиент и сервер могут передавать друг другу указатели на динамически выделяемые блоки памяти и о том, что в некоторых случаях память, выделенную сервером, освобождает клиент, и наоборот. Если к этому добавить то, что мы знаем о маршалинге, получится, что в случае внешнего сервера на самом деле память, выделенную сервером, освобождает его заглушка, а на стороне клиента заместитель снова выделяет память, которую затем и освобождает клиент. Понятно, что для выполнения таких операций клиент и заместитель, а также заглушка и сервер, должны пользоваться единым менеджером памяти. Ни New, ни GetMem не подходят для выделения памяти в таком случае, потому что менеджер памяти Delphi недоступен для заглушки и заместителя.

Разумеется, система предоставляет менеджер памяти, подходящий для использования в COM/DCOM. Мы уже сталкивались с функциями, которые его используют: это функции типа SysAllocString и SysFreeString для строк, а также все функции, связанные с выделением и освобождением памяти для безопасных массивов. Именно благодаря этому строки и безопасные массивы можно передавать между клиентом и сервером.

В общем случае работа с менеджером памяти осуществляется через интерфейс IMalloc. Указатель на этот интерфейс можно получить с помощью функции CoGetMalloc. Эта функция принимает два параметра, первый из которых зарезервирован и должен быть равен 1, второй параметр выходной, через него возвращается интерфейс IMalloc.

Примечание: Функция GoGetMalloc не требует предварительного вызова CoInitialize, так что данный менеджер памяти можно использовать и без инициализации COM. Именно поэтому в Delphi можно работать со строками типа WideString, которые используют данный менеджер памяти, не вызывая CoInitialize.

Интерфейс IMalloc содержит шесть методов: Alloc (выделяет блок памяти заданного размера), Realloc (изменяет размер выделенного ранее блока), Free (освобождает выделенный блок), GetSize (возвращает размер выделенного ранее блока), DidAlloc (позволяет определить, был данный блок выделен этим менеджером памяти) и HeapMinimize (возвращает неиспользуемые в данный момент блоки памяти системе).

В целом работать с системным менеджером памяти не сложнее, чем использовать функции GetMem и FreeMem. Метод HeapMinimize рекомендуется вызывать время от времени, чтобы эффективнее возвращать память системе (судя по всему, системный менеджер памяти работает по тому же принципу, что и менеджер памяти Delphi, т.е. приберегает освобождённую память на всякий случай, чтобы при следующем выделении не выполнять затратную операцию получения памяти у системы).

Существует альтернативный способ работы с системным менеджером памяти: через функции CoTaskMemAlloc, CoTaskMemRealloc и CoTaskMemFree. Эти функции — другой интерфейс к тому же менеджеру памяти: память, выделенную через CoTaskMemAlloc, можно освобождать через IMalloc.Free, а выделенную через IMalloc.Alloc — освобождать через CoTaskMemFree. А IMalloc.DidAlloc для блока, выделенного с помощью CoTaskMemAlloc, вернёт 1, что соответствует тому, что блок выделен данным менеджером памяти. Обычно функции CoTaskMemXXX удобнее, чем интерфейс IMalloc, так как не требуют предварительного вызова CoGetMalloc. Но методы GetSize, DidAlloc и HeapMinimize не имеют аналогов в виде отдельных системных функций, поэтому если они требуются приложению, следует использовать IMalloc.

Ничего подобного автоматической финализации данных в системном менеджере памяти нет. Другими словами, если вы освобождаете память, выделенную под какую-то структуру, а эта структура сама содержит ссылки на динамическую память (например, поля типа BSTR), то сначала вручную нужно освободить ту память, на которую указывают эти поля, а потом уже освобождать память, хранящую саму структуру.

Подчеркнём, что использование системного менеджера памяти необходимо тогда, когда память, выделяемая на одной стороне, может быть освобождена на другой; в остальных же случаях в этом нет необходимости. Например, для чисто входных параметров, передающихся по ссылке, клиент может выделять память где угодно, даже в стеке. Для указателей верхнего уровня в выходных параметрах, для которых память выделяется также клиентом, тоже можно использовать любой менеджер памяти, а также стек, глобальные переменные и т.п.


предыдущий урок содержание семинара следующий урок




Смотрите также материалы по темам:
[Технологии ActiveX, COM, DCOM] [Работа с памятью]

 Обсуждение материала нет сообщений
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования