См. Ранее очень хорошее замечание о различии между статическим и динамическим связыванием. Предполагая, что вы имеете в виду динамическое связывание, тогда:
Как загрузка, так и (динамическая) компоновка выполняются компоновщиком - в linux и других Unix-подобных системах это делается с помощью /lib/ld.so
, которая является реальной программой, запускаемой операционной системой практически во всех случаях. ld.so
в свою очередь загружает ваше приложение - mygameBinary
в память, а ld.so
затем читает из файла mygameBinary
список динамически связанных библиотек, которые ему требуются.
Затем компоновщик ld.so
загружает каждую из этих библиотек в память по очереди, например, libc.so
, libpthread.so
, libopengl.so
и рассматривает то, что могут потребоваться другим библиотекам для этих , например, libm.so
.
Как только загрузка завершена, начинается связывание , процесс поиска именованных объектов или функций, которые экспортируются одной библиотекой или приложением, и импортировано другой библиотекой или приложением. Затем компоновщик изменяет различные ссылки и иногда код для обновления несвязанных указателей данных и вызовов функций в каждой библиотеке, чтобы указать, где находятся фактические данные или функции. Например, вызов printf
в mygameBinary
начинает указывать на ничто (фактически он просто вызывает компоновщик), но после связывания становится переходом к функции printf
в libc
.
Как только эта связь будет завершена, приложение запускается, вызывая функцию _start
в mygameBinary
, которая затем вызывает main
, и ваша игра запускается.
Динамическое связывание таким образом необходимо для поддержки следующего:
- Обновления библиотеки после выпуска приложения, которые изменяют расположение функций и данных.
- одиночное приложение, работающее на разных версиях ОС
- неопределенность относительно того, где библиотека или приложение могут быть загружены в память
- уменьшает размер ядра, разделяя физическую память, используемую библиотеками, между несколькими приложениями.
Некоторые ОС различаются по деталям, например, OSX и AIX предварительно загружают определенный набор библиотек в фиксированные места в памяти. Это означает, что их не нужно загружать, просто связывать, что может быть быстрее.
Некоторые ОС, такие как OSX, а иногда и Linux, поддерживают предварительную связь, которая представляет собой процесс, при котором скрипт запускает приложения в вашей системе перед их запуском и выполняет связывание. Когда вы запускаете их, вам не нужно связывать их. Это важно, потому что связывание занимает значительную часть времени вашего компьютера при запуске приложения, и некоторые приложения могут запускаться несколько раз в секунду, например gcc
, cpp
и as
во время процесса создания приложения или фильтрации сценарии при индексации данных вашего компьютера (OSX Spotlight).