Компоновщик играет важную роль в построении C / C ++ для разрешения внешних зависимостей. Языки .NET не используют компоновщик.
Существует два вида внешних зависимостей, реализация которых доступна во время компоновки в другом файле .obj или .lib, предлагаемом в качестве входных данных для компоновщика. А те, что доступны в другом исполняемом модуле. DLL в Windows.
Компоновщик разрешает первые во время компоновки, ничего сложного не происходит, так как компоновщик будет знать адрес зависимости. Последний шаг сильно зависит от платформы. В Windows компоновщик должен быть снабжен библиотекой импорта. Довольно простой файл, который просто объявляет имя DLL и список экспортированных определений в DLL. Компоновщик разрешает зависимость, вводя переход в код и добавляя запись во внешнюю таблицу зависимостей, которая указывает местоположение перехода, чтобы его можно было исправлять во время выполнения. Загрузка DLL и настройка таблицы импорта выполняется во время выполнения загрузчиком Windows. Это вид с высоты птичьего полета, есть много скучных деталей, чтобы сделать это как можно быстрее.
В управляемом коде все это выполняется во время выполнения, управляемым JIT-компилятором. Он переводит IL в машинный код, управляемый выполнением программы. Всякий раз, когда выполняется код, ссылающийся на другой тип, JIT-компилятор включается в действие, загружает тип и транслирует вызываемый метод этого типа. Побочным эффектом загрузки типа является загрузка сборки, содержащей тип, если он не был загружен ранее.
Также заметна разница для внешних зависимостей, которые доступны во время сборки. Компилятор C / C ++ компилирует один исходный файл за раз, зависимости разрешаются компоновщиком. Управляемый компилятор обычно принимает все исходные файлы, которые создают сборку, вместо того, чтобы компилировать их по одному. Отдельная компиляция и компоновка фактически поддерживаются (.netmodule и al.exe), но не очень хорошо поддерживаются доступными инструментами и, следовательно, редко осуществляются. Кроме того, он не может поддерживать такие функции, как методы расширения и частичные классы. Соответственно, управляемому компилятору требуется гораздо больше системных ресурсов для выполнения работы. Легко доступны на современном оборудовании. Процесс сборки для C / C ++ был создан в эпоху, когда эти ресурсы были недоступны.