Почему я должен предоставлять компилятору файлы *.lib, которые использую только для некоторых библиотек?

Я следил за некоторыми учебными пособиями по использованию некоторых библиотек C для разработки игр в Windows. При использовании некоторых библиотек opengl (freeglut, glew) мне просто нужно скомпилировать с использованием «cl file.c», и если у меня есть нужные файлы dll в текущем каталоге, он будет скомпилирован и работать нормально.

Но для SDL я должен явно предоставить файлы lib, например. "cl sdlprog.c SDL2.lib SDL2main.lib". Я также должен указать, что это консольная программа с "/link/subsystem:console".

Почему мне нужно делать эти вещи для SDL? Программа opengl прекрасно компилируется без упоминания файлов lib.

Я убедился, что все файлы lib находятся в правильном месте. Они находятся там же, где я положил файлы opengl lib.


person J. Czekaj    schedule 10.06.2019    source источник
comment
Механика использования зависимостей сильно различается от SDK к SDK. Пример: сборка glew, о которой вы упоминаете, например, четко указывает на своем веб-сайте, что при использовании конфигурации общей библиотеки не забудьте связать свой проект с glew32.lib, glu32.lib и opengl32.lib в Windows и libGLEW. .so, libGLU.so и libGL.so в Unix (-lGLEW -lGLU -lGL). Что касается вашего вопроса, то простой ответ заключается в том, что именно так авторы SDL решили предоставить свою библиотеку для использования, и они вероятно, вы лучший источник для вопросов.   -  person WhozCraig    schedule 10.06.2019
comment
Не могли бы вы опубликовать часть вашего файла sdlprog.c? Меня интересуют макросы препроцессора (строки, начинающиеся с #).   -  person CristiFati    schedule 13.06.2019
comment
@CristiFati С тех пор я удалил его, потому что это была просто крошечная тестовая программа, которая инициализировала sdl. Но я почти уверен, что это был просто #include ‹SDL2/SDL.h›, причина, по которой SDL2 там, заключается в том, что я поместил заголовки sdl в include\SDL2.   -  person J. Czekaj    schedule 14.06.2019
comment
Вы должны предоставить MCVE ([SO]: Как создать минимальный, полный и проверяемый пример (mcve)), который должен содержать код, команду для его сборки, ошибку и команду, которая завершилась успешно.   -  person CristiFati    schedule 15.06.2019


Ответы (1)


Некоторые библиотеки загружаются динамически и доступны через указатели функций. В этих случаях библиотеки не должны быть явно связаны во время компиляции. Другие библиотеки могут быть скомпонованы статически, если они не требуют динамической загрузки, но линковка выполняется во время компиляции. Затем есть некоторые библиотеки, которые связаны во время компиляции, но они просто предоставляют простой в использовании интерфейс для процесса динамической загрузки. Хорошим примером этого является таблица адресов импорта в PE-файлах Win32. Например, вызов NtTerminateProcess находится в библиотеке ntdll. Вы можете вызвать NtTerminateProcess динамически, вызвав LoadLibrary и GetProcAddress, или вы можете связать время компиляции, что создаст для вас интерфейс; Однако ntdll по-прежнему необходимо будет динамически загружать во время выполнения. Связывание времени компиляции не было статичным, оно просто позволяло вам вызывать NtTerminateProcess без использования LoadLibrary/GetProcAddress.

Таким образом, вопрос сводится к разнице между статическим связыванием и тем, что делает opengl. Или динамическое связывание, которое требует sdl. И, как я упоминал ранее, динамическая загрузка, которая во время выполнения выделяет память для загружаемого модуля и загружает его по адресу, указанному ОС. Уже есть пост, который немного освещает это:

Разница между статической и динамической компоновкой

разница между динамической загрузкой и динамической компоновкой?

При статической компоновке, если ваша библиотека когда-либо изменится, вам нужно будет перекомпилировать двоичный файл. В случае динамической компоновки вам не нужно перекомпилировать бинарник, только dll.

person Nina    schedule 10.06.2019