Подтвердить что ты не робот

В чем разница между ссылками и загрузкой на языке c

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

4b9b3361

Ответ 1

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

Как загрузка, так и динамическая компоновка выполняются компоновщиком - на 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 поддерживают предварительную компоновку, это процесс, в котором script работает над приложениями в вашей системе, прежде чем запускать их, и делает ссылку. Когда вы запускаете их, вам не нужно связывать их. Это важно, потому что привязка занимает значительное время вашего компьютера при запуске приложения, а некоторые приложения могут запускаться несколько раз в секунду, например, gcc, cpp и as во время процесса сборки приложения или фильтра скрипты при индексировании данных вашего компьютера (OSX Spotlight).

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

Здесь есть подробное описание того, как это происходит, как хэшируются имена, насколько дорого нужно разрешать символы во время выполнения и т.д. в Как Создание общих библиотек.

Ответ 5

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) в память для запуска, который называется загрузкой.

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

Ответ 6

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

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

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

Ответ 7

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