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



         

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


то длина массива, размещенного на стороне сервера, будет вычислена, исходя из длины входной строки (эта длина равна шести с учетом заключительного нулевого символа). Рассмотрим следующую реализацию метода со стороны сервера:

HRESULT CFoo::Method27(OLECHAR *wsz) { DisplayString(wsz); // wsz only can hold 6 characters! // wsz может хранить только 6 символов! wcscpy(wsz, OLESTR("Goodbye")); return S_OK; }

Поскольку соответствие массива основывалось на величине wcslen(OLESTR("Hello")+1), то, когда реализация метода перезапишет в данную строку что-то более длинное, "хвост" этой строки перезапишет случайное число байтов памяти, что приведет к неисправимым ошибкам (будем надеяться, еще до выпуска данной программы в свет). Это означает, что, хотя вызывающая программа и имела достаточно памяти, заранее выделенной для записи результирующей строки, уровень маршалинга со стороны сервера не знал об этой кажущейся внешней памяти и выделил место, достаточное для хранения только шести символов строки Unicode. Код на IDL должен был быть таким:

HRESULT Method28([in] long cchMax, [in, out, string, size_is(cchMax)] OLECHAR *wsz);

а вызывающая программа могла бы использовать это так:

void f(IFoo *pFoo) { OLECHAR wsz[1024]; wcscpy(wsz, OLESTR("Hello")); pFoo->Method28(1024, wsz); // .. process updated string // .. обрабатываем обновленную строку }

Наиболее неприятным аспектом примера c [in, out, string] является то, что он прекрасно работает, когда входная строка имеет по крайней мере такую же длину, как выходная строка. Ошибки, связанные с этим методом, будут периодическими и могут ни разу не возникнуть на стадии тестирования проекта.

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


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