При загрузке программ в память, каково различие между динамическим подключением времени загрузки и динамическим подключением во время выполнения?
Эйден Белл покрыл основы, но добавим:
Время загрузки Динамическое связывание обычно осуществляется путем статически связывания вашего приложения к .lib
или .a
Файл, который содержит код для автоматической установления ссылок во время выполнения на символы, которые можно найти в .dll
или .so
файлов запуска программы. Обычно это для фиксированной функциональности (I.E. Библиотека времени выполнения C и т. Д.) И позволяет вашей программе пожинать преимущества исправлений ошибок в библиотеках при сохранении небольшого размера исполняемого размера (факторингом общий код в одну библиотеку).
Связывание времени выполнения используется для более динамических функций, таких как загрузка плагина. Как сказал Айден, вы используете LOBSLIBRARY ()
или эквивалентное для активного присоединения модулей в вашу программу во время выполнения, возможно, путем допрашивания каталога, содержащего DLL-каналы, загружающую каждого по очереди и разговаривая с плагином HOMEGROWN API. При этом ваша программа может загружать модули, которые даже не существовали, когда ваше приложение было скомпилировано / связано, и, таким образом, может расти органически после развертывания.
Принципиально оба метода в конечном итоге вызывают API API
, но используя фиксированный набор символов и библиотек в прежнем случае и более динамичный набор в последнем.
Ссылки нагрузки нагрузки - это когда символы в библиотеке, указанные исполняемым (или другой библиотекой), обрабатываются, когда исполняемая / библиотека загружается в память операционной системой.
Связывание времени выполнения - это при использовании API, предоставленной ОС или через библиотеку, чтобы загрузить DLL или DSO, когда вам это нужно, и выполните разрешение символа.
Я знаю больше о Linux DSOS, чем Windows DLL, но принцип должен быть одинаковым. .NET Библиотеки могут отличаться.
В Linux архитектуры плагинов делаются таким образом. Ваша программа будет использовать время выполнения, чтобы загрузить библиотеку и вызывать некоторые функции. Тогда, возможно, выгрузить его. Это также позволяет нескольким библиотекам с теми же символами, экспортированными для нагрузки без столкновения. Я думаю, что dlls будет работать таким же тем же способом.
исполняемые файлы имеют «пустые пробелы» в их символьных таблицах, которые нуждаются в заполнении какой-то библиотекой. Эти пустые пробелы обычно заполняются при нагрузке или время компиляции. Вы можете отрицать необходимость «пустых пробелов» в таблице символов, используя соединение времени выполнения.
Другим сценарием, когда связывание времени выполнения является полезным, предназначена для отладки библиотек или выбора из нескольких совместимых библиотек ABI / API во время выполнения. У меня часто есть библиотека, скажем, «Foo» и один под названием «Foo_unstable» и имел тестовое приложение, которое переключается между 2 и делает некоторые тестирование.
Под Linux, чтобы увидеть, какие библиотеки исполняемые ссылки на время нагрузки вы запускаете команду LDD
и получаете вывод, такие как (ON / BIN / LS):
linux-vdso.so.1 => (0x00007fff139ff000)
librt.so.1 => /lib64/librt.so.1 (0x0000003c4f200000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003c4fa00000)
libcap.so.2 => /lib64/libcap.so.2 (0x0000003c53a00000)
libacl.so.1 => /lib64/libacl.so.1 (0x0000003c58e0000
Операционная система будет пытаться загрузить библиотеки (файлы .so) при нагрузке. У него уже может быть библиотека в памяти.