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


Полиморфизм на этапе выполнения - часть 2


Если описание интерфейса IFastString дано как общедоступное (publicly available), то ничто не препятствует как исходному конструктору (implementor) FastString, так и любым сторонним средствам реализации порождать дополнительные классы реализации от того же самого интерфейса. Подобно исходной реализации класса FastString, эти новые реализации будут иметь такое двоичное представление, что будут совместимы на двоичном уровне с исходным классом интерфейса. Все, что должен сделать пользователь, чтобы добиться полностью совместимых ("plug-compatible") реализаций, — это определить правильное имя файла для желаемой реализации DLL.

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

IFastString * CallCreateFastString(const char *psz, bool bLeftToRight = true) { static IFastString * (*pfnlr)(const char *) = 0; static IFastString * (*pfnrl)(const char *) = 0; IFastString *(**ppfn) (const char *) = &pfnlr; const TCHAR *pszDll = _TEXT("FastString.DLL"); if (!bLeftToRight) { pszDll = _TEXT("FastStringRL.DLL"); ppfn = &pfnrl; } if (!(*ppfn)) { // init ptr 1st time through // первое появление ptr const char szFn[] = "CreateFastString"; HINSTANCE h = LoadLibrary(pszDll); if (h) *(FARPROC*)ppfn = GetProcAddress(h, szFn); } return (*ppfn) ? (*ppfn)(psz) : 0; }

Когда клиент вызывает функцию без второго параметра,

pfs = CallCreateFastString("Hi Bob!"); n = pfs->Find("ob");

то загружается исходная DLL FastString, и поиск идет слева направо. Если же клиент указывает, что строка написана на разговорном языке, анализируемом справа налево:

pfs = CallCreateFastString("Hi Bob!", false); n = pfs->Find("ob");

то загружается альтернативная версия DLL (FastStringRL.DLL), и поиск будет начинаться с крайней правой позиции строки. Главное здесь то, что вызывающие операторы CallCreateFastString не заботятся о том, какая из DLL используется для реализации методов объекта. Существенно лишь то, что указатель на совместимый с IFastString vptr возвращается функцией и что vptr обеспечивает успешное и семантически корректное функционирование. Эта форма полиморфизма на этапе выполнения чрезвычайно полезна при создании системы, динамически скомпонованной из двоичных компонентов.




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



Книжный магазин