Читаем Сущность технологии СОМ. Библиотека программиста полностью

Программа, вызывающая метод GetFromPound, ответственна за освобождение любой памяти, выделенной вызываемым методом, после использования соответствующих значений:

DOG fido;

HRESULT hr = p->GetFromPound(&fido);

if (SUCCEEDED(hr)) {

printf(«The dog %h is owned by %h», fido.nDogID, fido.pOwner->nHumanID);

// data has been consumed, so free the memory

// данные использованы, поэтому освобождаем память

CoTaskMemFree(fido.pOwner);

}

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

В только что приведенном примере использован чистый [out]-параметр. Управление [in, out]– параметрами несколько более сложно. Вложенные указатели для [in, out]-параметров должны быть размещены вызывающей программой с помощью распределителя памяти задачи. Если методу требуется повторно распределить память, переданную клиентом, то метод должен сделать это с использованием CoTaskMemRealloc. Если же вызывающая программа не имеет никакой информации для передачи методу, то она может передать ему на входе нулевой указатель, и тогда метод может использовать CoTaskMemRealloc (который без проблем принимает нулевой указатель и делает то, что нужно). Подобным же образом, если у метода нет информации для обратной передачи в вызывающую программу, он может просто освободить память, на которую ссылается вложенный указатель. Рассмотрим следующее определение метода IDL:

HRESULT SendToVet([in, out] DOG *pDog);

Пусть у вызывающей программы имеется легальное значение HUMAN, которое она хочет передать как параметр. Тогда клиентский код может выглядеть примерно так:

HUMAN *pHuman = (HUMAN*)CoTaskMemAllocc(sizeof(HUMAN));

pHuman->nHumanID = 1522;

DOG fido = { 4111, pHuman };

HRESULT hr = p->SendToVet(&fido); // [in, out]

if (SUCCEEDED(hr)) {

if (fido.pOwner)

printf(«Dog is now owned by %h», fido.pOwner->nHumanID);

CoTaskMemFree(fido.pOwner);

// OK to free null ptr.

// можно освободить нулевой указатель

}

Реализация метода могла бы повторно использовать буфер, используемый вызывающей программой, или выделить новый буфер в случае, если вызывающая программа передала нулевой вложенный указатель:

STDMETHODIMP MyClass::SendToVet(/*[in, out]*/DOG *pDog)

{

if (fido.pOwner == 0)

fido.pOwner = (HUMAN*)CoTaskMemAlloc(sizeof (HUMAN));

if (fido.pOwner == 0)

// alloc failed

// сбой выделения памяти

return E_OUTOFMEMORY;

fido.pOwner->nHumanID = 22;

return S_OK;

}

Поскольку работа с [in,out]-параметрами в качестве вложенных указателей имеет ряд тонкостей, в документации на интерфейс часто повторяются правила управления памятью для вложенных указателей.

Приведенные выше фрагменты кода используют наиболее удобный интерфейс для СОМ-распределителя памяти задач. До появления версии СОМ под Windows NT основная связь с распределителем памяти задачи осуществлялась через его интерфейс IMallос:

[ uuid(00000002-0000-0000-C000-000000000046),local,object]

interface IMalloc : IUnknown {

void *Alloc([in] ULONG cb);

void *Realloc ([in, unique] void *pv, [in] ULONG cb);

void Free([in, unique] void *pv);

ULONG GetSize([in, unique] void *pv);

int DidAlloc([in, unique] void *pv);

void HeapMinimize(void);

}

Для получения доступа к интерфейсу IMalloc распределителя памяти задачи в СОМ имеется API-функция CoGetMalloc:

HRESULT CoGetMalloc(

[in] DWORD dwMemCtx, // reserved, must be one

// зарезервировано, должно равняться единице

[out] IMalloc **ppMalloc); // put it here!

// помещаем его здесь!

Это означает, что вместо вызова удобного метода CoTaskMemAlloc:

HUMAN *pHuman = (HUMAN*)CoTaskMemAlloc(sizeof(HUMAN));

можно использовать следующую менее удобную форму:

IMalloc *pMalloc = 0;

pHuman = 0;

HRESULT hr = CoGetMalloc(1, &pMalloc);

if (SUCCEEDED(hr)) {

pHuman = (HUMAN*)pMalloc->Alloc(sizeof(HUMAN));

pMalloc->Release();

}

Преимущество последней технологии заключается в том, что она совместима с ранними, до Windows NT, версиями СОМ. Но в целом предпочтительнее использовать CoTaskMemAlloc и другие, поскольку эти методы требуют меньше программного кода и поэтому меньше подвержены ошибкам программирования.

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных