А оказывается, многие известные люди считают, что динамическое связывание это дурь и блажь. Серьёзное приложение-де не может находиться в зависимости от каких-то там обновляемых системных библиотек. В самом деле, от несанкционированных обновлений может быть не только польза (баг поправят, или там дыру закроют), но и серьёзный вред. При этом, оказывается, исправление бага в системной либе может быть полезно для одних приложений и вредно для других. Получается, и обновлять нельзя, и не обновлять нельзя.
Про поломку бинарной совместимости и говорить нечего, см. DLL Hell. Версионирование библиотек, придуманное для решения этой проблемы, по большому счёту только усугубляет её.
Короче, серьёзные приложения все свои библиотеки носят с собой, и в итоге ни память не экономится, ни место на диске, и сама идея динамически связываемых библиотек превращается в профанацию.
Статическое связывание, напротив, всё упрощает! Из-за отсутствия необходимости в PIC код становится много компактнее (что в большей части случаев перевешивает расходы на дублирование кода в приложениях), межмодульные оптимизации становятся возможны, плюс к тому экономятся драгоценные TLB. При этом ещё не надо забывать о том, что код нескольких копий одного процесса тоже является общим (равно как и код форкнутого процесса с родительским), то есть экономия памяти тоже не очень-то страдает.
Ещё одна причина, по которой используют динамически связываемые библиотеки — это разного рода плагины. Но для механизма плагинов этого динамическое связывание не является необходимостью. Достаточно динамической загрузки кода. Кстати, Windows DLL это как раз и есть динамически загружаемые, а не связываемые, библиотеки. Динамического связывания в Windows вообще нет. Код DLL не является position-independent.
Тут бы и подумать, что Windows со своими DLL идёт впереди прогресса, не поддаваясь на провокации. Но нет. Во-первых, само присутствие DLL как отдельных системных файлов порождает проблемы, о которых сказано в первых четырёх абзацах. Почему-то принято завязываться на DLL, а не линковать всё статически. Почему? Неизвестно.
Во-вторых, в Windows очень капризная libc. Она не переносит, когда память, выделенная в одном экземпляре, освобождается в другом! Из личного опыта скажу, что даже strcpy-ровать её нельзя, хотя по ссылке этого не написано. Что делает статическую линковку с libc бессмысленной в том случае, когда у вам есть более-менее сложные плагины. Приложения и их плагины должны линковаться с динамической libc. И вообще, в Windows море проблем с написанием плагинов.
Говорят (по самой первой ссылке) что в plan9 статическая линковка и всё при этом просто и удобно, в том числе с плагинами. Хотя и плагины там не очень нужны, при наличии 9P. Сам не пробовал, подтвердить не могу.
Подписаться на:
Комментарии к сообщению (Atom)
2 комментария:
а вообще вот что нужно, так это динамическая загрузка модулей, как в Blackbox Component Pascal.
вот это пример того, как динамические библиотеки могут быть реализованы правильно.
другой пример того, как эта же задача может быть решена проще:
объектная модель SOM в OS/2. минусы её в том, что это реализация тяжеловесной CORBA, а значит, маршаллинг и какая-то внутренняя жизнь при создании объектов, например работа с метаклассами.
плюсы же в том, что решается проблема с бинарной совместимостью "малой кровью": для того, чтобы сделать SOM объект с каким-то классом, достаточно экспортировать в DLL всего три функции (сравните это с тем, что порождает типичная библиотека на С++).
бинарная совместимость решается правильным проектированием структур, реализующих объекты: ClassDataObject, который содержит ссылку на метакласс и указатели на методы. заполняется в конструкторе класса, то есть, экспортировать все методы в библиотеку не нужно.
ещё в releaseorder поле в IDL указывается "раскладка" объекта в том виде, который не ломает бинарную совместимость.
да, и как в Blackbox Component Pascal здесь тоже методы привязаны к классам не так топорно, как в С++.
в итоге, имеем 2 системы, где динамические библиотеки реализованы правильно: SOM и Oberon-2, Blackbox Component Pascal.
или, "компонентное программирование" Клеменса Шиперски.
но они широко практически не известны и мало используются.
Отправить комментарий