Хорошо. Когда вы включаете math.h
, компилятор будет читать файл, содержащий объявления функций и макросов, которые можно использовать. Если вы вызываете функцию, объявленную в этом файле ( header ), то компилятор вставляет инструкцию вызова в это место в вашем объектном файле, который будет сделан из файла, который вы компилируете (давайте назовем его test.c
и объектный файл создан test.o
). Он также добавляет запись в таблицу перемещений этого объектного файла:
Relocation section '.rel.text' at offset 0x308 contains 1 entries:
Offset Info Type Sym.Value Sym. Name
0000001c 00000902 R_386_PC32 00000000 bar
Это будет запись перемещения для функциональной панели. Будет сделана запись в таблице символов, отметив, что функция еще не определена:
9: 00000000 0 NOTYPE GLOBAL DEFAULT UND bar
Когда вы связываете объектный файл test.o
с программой, вам нужно связать ее с математической библиотекой с именем libm.so
. Расширение so
аналогично расширению .dll
для Windows. Это означает, что это общий объектный файл . При компиляции компилятор исправит все места, которые появляются в таблице перемещений test.o
, заменив свои записи соответствующим адресом функции bar. В зависимости от того, используете ли вы совместно используемую версию библиотеки или статическую (тогда она называется libm.a
), компилятор сделает это исправление после компиляции или позже, во время выполнения, когда вы фактически запускаете свою программу. Когда закончите, он вставит запись в таблицу общих библиотек, необходимых для этой программы. (можно показать с помощью readelf -d ./test
):
Dynamic section at offset 0x498 contains 22 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libc.so.6]
... ... ...
Теперь, если вы запустите вашу программу, динамический компоновщик найдет эту библиотеку и свяжет эту библиотеку с вашим исполняемым образом. В Linux эта программа называется ld.so
. Статическим библиотекам нет места в динамическом разделе, поскольку они просто связаны с другими объектными файлами, и о них забывают; с тех пор они являются частью исполняемого файла.
На самом деле все гораздо сложнее, и я также не понимаю этого в деталях. Это грубый план.