каково различие между соединением и загрузкой на языке C

Соединение и загрузка динамические библиотеки оба происходят во времени выполнения? или случается так, что только загрузка библиотеки происходит во время выполнения?

14
задан Vijay 23 December 2009 в 09:57
поделиться

7 ответов

См. Предыдущий очень хороший момент о различии между статическим и динамическим связыванием. Предполагая, что вы имеете в виду динамическое связывание, тогда:

И загрузка, и (динамическое) связывание выполняется компоновщиком - в Linux и других Unix-подобных системах это делается с помощью /lib/ld.so , которая фактически является программой, запускаемой операционной системой почти во всех случаях. ld.so , в свою очередь, загружает ваше приложение - mygameBinary в память и ld. поэтому затем считывает из файла mygameBinary список требуемых динамически подключаемых библиотек.

Компоновщик, ld.so , затем загружает каждую из этих библиотек в память по очереди, например libc.so , libpthread.so , ] libopengl.so , и смотрит, какие другие библиотеки могут потребоваться этим , например libm.so .

Как только загрузка завершена, затем начинается связывание , процесс просмотра именованных объектов или функций, которые экспортируются одной библиотекой или приложением и импортируются другой библиотекой или приложением. Затем компоновщик изменяет различные ссылки, а иногда и код для обновления несвязанных указателей данных и вызовов функций в каждой библиотеке, чтобы указать, где находятся фактические данные или функция. Например, вызов printf в mygameBinary начинается с того, что не указывает ни на что (на самом деле он просто вызывает компоновщик), но после связывания становится переходом к printf функция в libc .

После завершения связывания приложение запускается путем вызова функции _start в mygameBinary , которая затем вызывает main , и ваша игра запустится.

Динамическое связывание таким способом необходимо для поддержки следующего:

  • обновления библиотеки после выпуска приложения, которые изменяют расположение функций и данных.
  • одно приложение, работающее на разных версиях ОС
  • неопределенность относительно того, где библиотека или приложение могут быть загружены в память
  • уменьшить размер ядра за счет совместного использования физической оперативной памяти, используемой библиотеками, между несколькими приложениями.

Некоторые ОС различаются деталями, например, OSX и AIX предварительно загружают определенный набор библиотек в фиксированные места в памяти. Это означает, что их не нужно загружать, их нужно просто связывать, что может быть быстрее.

Некоторые ОС, такие как OSX и иногда Linux, поддерживают предварительное связывание, то есть процесс, при котором сценарий запускается поверх приложений в вашей системе перед вы запускаете их, и делаете линковку. Когда вы их запускаете, связывать их не нужно. Это важно, потому что связывание занимает значительную часть времени вашего компьютера при запуске приложения,

18
ответ дан 1 December 2019 в 10:02
поделиться

Как динамическое связывание, так и загрузка библиотеки происходят во время выполнения, но динамическое связывание выполняется до выполнения программы и выполняется системным компоновщиком. Так, например, если требуемые библиотеки отсутствуют, программа не может быть выполнена. Загрузка библиотеки, с другой стороны, выполняется самой программой через функции dlopen / LoadLibrary. В этом случае процесс загрузки контролируется приложением, которое может, например, обрабатывать ошибки.

-1
ответ дан 1 December 2019 в 10:02
поделиться

file01.c, file02.c -> производит -> file01.o, file02.o -> Эта информация .o объединяется и помещается в единую динамическую библиотеку, то есть lib1.a file11.c, file12.c -> производит -> file11.o, file12.o -> Эта информация .o объединяется и помещается в единую динамическую библиотеку lib2.a

Теперь у меня есть 2 библиотеки, которые, наконец, связаны вместе для создания исполняемого файла (например, .elf, .mot или .fls). Этот процесс связывания информации из lib1.a и lib2.a для формирования единого исполняемого файла называется компоновкой.

Теперь мне нужно загрузить это в память, чтобы запустить его и увидеть поведение окончательного исполняемого файла. Процесс загрузки окончательного исполняемого файла (например, .elf, .mot или .fls) в память для запуска называется загрузкой.

Я надеюсь, что это проясняет важность связывания и загрузки (однако определения не подходят : -)).

1
ответ дан 1 December 2019 в 10:02
поделиться

Сшивка - это процесс взятия нескольких небольших исполняемых файлов и объединения их в один большой исполняемый файл.

Загрузка - это загрузка исполняемого файла в память перед выполнением.

6
ответ дан 1 December 2019 в 10:02
поделиться

Оба случая происходят во время исполнения динамических библиотек.

Во-первых, загружаются библиотеки вместе со всеми их зависимостями (и зависимостями этих библиотек, и так далее). Затем динамический компоновщик решает символы в загруженных библиотеках. Обычно обе эти функции реализуются одним и тем же программным обеспечением; в Linux это ld.so.

Символы в статических библиотеках разрешаются во время компоновки и включаются в сам исполняемый файл. Однако, в статических библиотеках могут быть неразрешенные символы, которые удовлетворяются во время выполнения динамическими библиотеками.

В How to Write Shared Libraries есть подробное описание того, как это происходит, как хэшируются имена, как дорого стоит разрешение символов во время выполнения и т.д.

How to Write Shared Libraries.
1
ответ дан 1 December 2019 в 10:02
поделиться

Windows и Unix-системы используют совершенно разные подходы к динамическим библиотекам.

Windows DLL не связаны. Следовательно, вы не можете разделять статические объекты между DLL. Это как отдельная программа в вашем адресном пространстве.

Разделяемые Unix-объекты действительно "связаны" во время выполнения, так же как и различные модули одного и того же проекта, выполняющие разрешение символов.

-1
ответ дан 1 December 2019 в 10:02
поделиться

Существует два типа линковки: статическое линковка и динамическое линковка.

Статическая линковка происходит во время компиляции, а значит, перед загрузкой программы. При статическом связывании внешние символы, используемые вашей программой (например, имена функций), разрешаются во время компиляции.

Динамическое связывание происходит во время выполнения, то есть происходит после или во время загрузки программы. При динамическом связывании символы разрешаются либо во время загрузки, либо во время выполнения при обращении к символу (ленивая привязка). Последнее встречается чаще.

.
3
ответ дан 1 December 2019 в 10:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: