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


Типы данных - часть 7


// invoke method // вызываем метод HRESULT hr = p->SetString(_UBSTR(OLESTR("Hello")));

Заметим, что в промежуточном классе UBSTR могут быть в равной степени использованы строки типов char и wchar_t.

При передаче из метода строк через параметры типа [out] объект обязан вызвать SysAllocString, чтобы записать результирующую строку в буфер. Затем вызывающий объект должен освободить буфер путем вызова SysFreeString. Рассмотрим следующее определение метода:

HRESULT GetString([out, retval] BSTR *pbstr);

При реализации метода потребуется создать новую BSTR-строку для возврата вызывающему объекту:

STDMETHODIMP MyClass::GetString(BSTR *pbstr) { *pbstr = SysAllocString(OLESTR("Coodbye!")) ; return S_OK; }

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

extern OLECHAR g_wsz[]; BSTR bstr = 0; HRESULT hr = p->GetString(&bstr); if (SUCCEEDED(hr)) { wcscpy(g_wsz, bstr); SysFreeString(bstr); }

Тут нужно рассмотреть еще один важный аспект BSTR. В качестве BSTR можно передать нулевой указатель, чтобы указать на пустую строку. Это означает, что предыдущий фрагмент кода не совсем корректен. Вызов wcscpy:

wcscpy(g_wsz, bstr);

должен быть защищен от возможных нулевых указателей:

wcscpy (g_wsz, bstr ? bstr : OLESTR(""));

Для упрощения использования BSTR в заголовочном файле ustring.h содержится простая встраиваемая функция:

intline OLECHAR *SAFEBSTR(BSTR b) { return b ? b : OLESTR(""); }

Разрешение использовать нулевые указатели в качестве BSTR делает тип данных более эффективным с точки зрения использования памяти, хотя и приходится засорять код этими простыми проверками.

Простые типы, показанные на рис. 2.6, могут компоноваться вместе с применением структур языка С. IDL подчиняется правилам С для пространства имен тегов (tag namespace). Это означает, что большинство IDL-определений интерфейсов либо используют операторы определения типа (typedef):




Начало  Назад  Вперед