Когда DLL связана с основной программой, только интерфейс, то есть классы, функции и т. Д., Которые она экспортирует, связаны их сигнатурой. Фактический машинный код внутри DLL загружается только во время выполнения, а не во время компиляции; вот почему вы можете создать свое приложение, используя только библиотеку DLL, и поместить реальную библиотеку DLL туда, где она вам нужна (например, в какую-нибудь общую папку DLL или что-то в этом роде).
Затем вы можете поменять эту DLL с любой другой DLL с тем же интерфейсом. Именно так обычно работают системы плагинов, так как каждый плагин представляет собой просто DLL, которая соответствует задокументированному предварительно определенному интерфейсу, и программа просто загружает все библиотеки DLL того интерфейса, которые она находит, в некоторый каталог «плагинов».
(возможно) сбивающая с толку часть заключается в том, что фактически существует два вида файлов .lib:
а) библиотеки для статической компоновки. Они помещают весь свой скомпилированный код непосредственно в основное приложение и являются фиксированной частью результирующего файла .exe.
б) библиотеки для динамической компоновки. Они содержат интерфейс для библиотеки DLL, содержащей фактический код, который должен быть доступен приложению только во время выполнения (и если это не так, он не запустится, а просто скажет, какую библиотеку DLL он не может найти).
Кстати: вам не нужно указывать, на какую из ссылок вы ссылаетесь, какой тип, он делает это автоматически.
Кроме того: некоторые приложения создаются как библиотеки DLL, предназначенные для запуска во внешней среде. Например, веб-сервисы реализованы в виде библиотек DLL с определенным интерфейсом, который запускается сервером Apache / IISAPI / любым другим сервером. Это работает аналогично вышеупомянутой системе плагинов, но здесь каждая DLL эффективно является приложением.