Программирование на Visual C++. Архив рассылки - Алекс Jenter
Шрифт:
Интервал:
Закладка:
Группа операционных систем громким криком, как забытый средний ребенок, потребовала внимания, сказав, что нам следует готовиться к Cairo, некой таинственной хреновине, которую никогда не могли даже толком описать, не то, что выпустить. К их чести, следует сказать, что они не представляли концепции "System File Protection", исключающей DLL Hell. Но тут некая группа в Microsoft нашла фатальный недостаток в Java – её писали не они! Это было исправлено созданием то ли J, то ли Jole, а может, и ActiveJ (если честно, я просто не помню), точно такого же как Java, но другого. Это было круто, но Sun засудило Microsoft по какому-то дряхлому закону. Это была явная попытка задушить право Microsoft выпускать такие же продукты, как у других, но другие.
Помните менеджера по J/Jole/ActiveJ, стучащего по столу туфлей и говорящего, что Microsoft никогда не бросит этот продукт? Глупец! Все это означало только одно – недостаток внимания к группе ActiveX (или это был COM?). Эта невероятно жизнерадостная толпа вернулась с COM+ и MTS наперевес (может, это стоило назвать ActiveX+?). Непонятно почему к MTS не приставили COM или Active или X или + – они меня просто потрясли этим! Они также грозились добавить + ко всем модным тогда выражениям. Примерно тогда же кое-кто начал вопить про Windows DNA (почему не DINA) и "Windows Washboard", и вопил некоторое время, но все это почило раньше, чем все поняли, что это было.
К этому моменту Microsoft уже несколько лет с нарастающей тревогой наблюдала за интернет. Недавно они пришли к пониманию, что у Интернет есть фатальный недостаток: ну, вы поняли. И это приводит нас к текущему моменту и технологии .NET (произносится как "doughnut" (пончик по-нашему), но по-другому), похожей на Интернет, но с большим количеством пресс-релизов. Главное, что нужно очень четко понимать – .NET исключает DLL Hell.
В .NET входит новый язык, C#, (выясняется, что в Active++ Jspresso был фатальный недостаток, от которого он и помер). .NET включает виртуальную машину, которую будут использовать все языки (видимо, из-за фатальных недостатков в процессорах Интел). .NET включает единую систему защиты (есть все-таки фатальный недостаток в хранении паролей не на серверах Microsoft). Реально проще перечислить вещи, которых .NET не включает. .NET наверняка революционно изменит Windows-программирование… примерно на год.
Еще одну версию причин ломки старого можно прочесть в статье про C#.
Ну да ладно, давайте попробуем разобраться, чем же так хороша новая концепция, что из-за нее бросаются все прошлые наработки.
Новаторства CLRCLR – новая реализация идей, впервые в общедоступной форме изложенных в модели программирования COM. В CLR программисты загружают компоненты по типу, а не имени файла; разрешают точки входа, используя операции приведения типов, а не символьные точки входа. Модель программирования CLR в фундаментальном отношении не отличается от модели программирования COM. Итак, если модель программирования CLR так похожа модель программирования COM, зачем она вообще нужна? Ответ лежит в реализации.
По мнению группы разработчиков CLR из Microsoft, корень всех проблем кроется в эволюции информации о типах COM. Первые COM– интерфейсы вообще не имели универсального описания. Потом ввели IDL. Он был предназначен для генерации proxy/stub-DLL, которая, в свою очередь, использовалась dk вызовов методов интерфейсов между процессами или удаленными компьютерами.
Параллельно развивалась ветка VB, в которой появились бинарные описания компонентов под названием OLB (Object Library). Впоследствии OLB превратились в TLB (Type Library) но сути своей от этого не поменяли. Сначала в TLB-описаниях можно было использовать только очень ограниченный набор подтипов, что не давало применять их как единый стандарт описания компонентов. Так что существовало три вида описания типов: IDL, библиотеки типов и генерируемые MIDL /Oicf-строки, вставляемые внутрь proxy/stub-DLL. Ни один из этих трех форматов не стал абсолютным стандартом, и в одном формате можно записать информацию, которую невозможно представить в двух других. Это усложняло жизнь как разработчикам инфраструктуры COM, так и обычным программистам, создающим приложения из компонентов. Со временем библиотеки типов стали стандартом де-факто, но возможность обходиться без них, а иногда и вообще обходиться без описания типов, создавала некоторую неопределенность. Так, описание большинства низкоуровневых интерфейсов доступно только в виде заголовочных файлов C++, и, значит, недоступно для разработчиков, использующих более высокоуровневые языки типа VB или Java (например, OLE 2 API, или OLE DB API).
К тому же библиотеки типов COM описывают только типы, экспортированные из компонента. Информация об экспортированных типах позволяет средствам, работающим с COM, реализовать возможности наподобие IntelliSense в Visual Basic или декларативной архитектуры сервисов COM+. Это замечательно, но, по мнению господ из Microsoft, этого недостаточно. В COM не было возможности определить, от каких внешних компонентов зависит компонент. В то время как COM здорово поработал, чтобы сделать dumpbin.exe /exports устаревшим, он ничего не сделал, чтобы заменить dumpbin.exe /imports. Отсутствие информации о зависимостях затрудняет верное определение состава DLL (и их версий), необходимых для нормальной работы компонента.
Вот если бы хранить в библиотеке типов не только информацию об экспортированных вовне типах, а еще и обо всех (в том числе внешних) остальных типах, используемых в библиотеке… Тогда можно было бы точно определять список компонентов, а через них и библиотек, от которых зависит наша библиотека. К тому же это сделало бы возможным создание ряда сервисов, например, автоматической сериализации, отслеживания графа объекта, или автоматического принятия пре– и пост-условий. Большинство разработчиков, использующих COM в своей работе, давно хотели иметь полную информацию о типах. Все эти возможности заложены в CLR.
Главное достоинство CLR – всепроникающая, расширяемая, качественная информация о типах. В CLR все типы – а не только экспортированные из компонента – имеют runtime-описания типов. В CLR вы можете перейти к любому объекту и исследовать каждый аспект его определения типов, включая его представление. Это фундаментальный отход от классического COM, где открытые (public) интерфейсы были доступны, но представление объекта было скрыто.
Но вы можете заметить, что многие языки программирования имеют свою, встроенную информацию о типах. Правильно, но в большинстве случаев, это информация времени компиляции. Она недоступна, если объект не загружен, или извне этого объекта. К тому же нет единого стандарта информации о типах для языков программирования. CLR и является таким универсальным и переносимым между языками стандартом, предоставляющим информацию о типах в любой момент времени, вне зависимости от того, загружен объект в данный момент или нет.
Попробуем подытожить вышесказанное, перечислив усовершенствования, внесённые CLR в компонентную модель, попутно сравнивая эти усовершенствования с уже имеющимися в COM и других компонентных и околокомпонентных архитектурах.
Сборки. Сборки, или в оригинале Assembly – это логическая коллекция типов, описывающая объекты, которые могут быть реализованы в нескольких модулях (DLL или EXE). Сборка определяет область имен (типов), снимая надобность в GUID-ах для каждого типа. Так как имена сборок не могут повторяться, коллизии имен типов случиться также не может.
Для компонентов, используемых в рамках одного приложения, имена файлов сборки достаточно уникальны. CLR-сборки, в которых содержатся разделяемые компоненты (используемые совместно несколькими приложениями), можно присвоить (strong names). Строго именованная сборка имеет 128-битный публичный ключ, который идентифицирует разработчика компонента. Когда программа-клиент связывается со строго именованной сборкой, 64-битный хеш публичного ключа сохраняется в метаданных этой программы. Во время исполнения публичный ключ сборки сравнивается с 64-битным хешем, хранящимся в метаданных клиента, обеспечивая загрузку нужной сборки.
В COM для обеспечения уникальности почти каждому типу соответствует 128-битный GUID. В CLR каждая сборка имеет 128-битный публичный ключ, что, в сочетании с локально уникальными символьными именами типов, обеспечивает глобальную уникальность описания типов. Оба способа дают примерно одинаковый эффект, но способ CLR позволяет избежать работы с GUID– ами внутри приложений.
Единый стандарт обмена метаданными. Как уже говорилось раньше, информация о типах в COM передавалась в текстовой (IDL, заголовочные файлы) или в бинарной (TLB) форме. В CLR, напротив, информация о типах всегда передается в одной и той же документированной бинарной форме. Все работающие с CLR средства и компиляторы выдают и принимают метаданные в этом формате. Так, при определении набора интерфейсов разработчик может использовать свой любимый язык программирования и компилятор для создания описаний типов, вместо того, чтобы использовать один синтаксис (IDL) при описании типов и другой (например, C++ или Visual Basic) при их реализации.