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



         

Массивы - часть 12


Это необходимо, поскольку фактический размер результата может быть известен только внутри реализации метода. Этот динамически выделенный буфер возвращается программе, вызвавшей метод, и после того, как буфер уже не нужен, вызывающая программа должна освободить этот буфер распределителем памяти задачи в вызываемом процессе. Чтобы выразить эту идиому для строкового параметра, приведем следующий корректно работающий код IDL:

HRESULT Method29([out, string] OLECHAR **ppwsz);

из которого следует такая реализация со стороны сервера:

HRESULT CFoo::Method29(OLECHAR **ppwsz) { const OLECHAR wsz[] = OLESTR("Goodbye"); int cb = (wcslen(wsz) + 1) * sizeof(OLECHAR); *ppwsz = (OLECHAR*)CoTaskMemAlloc(cb); if (*ppwsz == 0) return E_OUTOFMEMORY; wcscpy(*ppwsz, wsz); return S_OK; }

Для правильного использования этого метода необходим такой код со стороны клиента:

void f(IFoo *pFoo) { OLECHAR *pwsz = 0; if SUCCEEDED(pFoo->Method29(&pwsz)) { DisplayString(pwsz); CoTaskMemFree(pwsz); } }

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

Синтаксис массива, приведенный в этом разделе, является совершенно разумным для программистов на С и C++. К сожалению, в то время, когда пишется этот текст, Visual Basic не способен работать ни с какими массивами переменной длины и может воспринимать только массивы фиксированной длины. Для того чтобы позволить Visual Basic посылать и получать массивы переменной длины, файлы СОМ IDL определяют среди прочих составной тип, именуемый SAFEARRAY. SAFEARRAY — это довольно редко используемая структура данных, которая позволяет передавать в качестве параметров многомерные массивы, совместимые с типом VARIANT. Для определения размеров массива SAFEARRAY в СОМ предусмотрен тип данных SAFEARRAYBOUND:




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