Добрый вечер. Все никак не могу понять одну банальнейшую вещь в C++.
Вот хотим мы скомпилировать исполняемый файл. Тут все просто, заголовочные файлы инклудятся в нужное место с объявлениями нужных функций, а мы пяшем от счастья.
Но что касается библиотек. Как я могу использовать заголовочный файл для подключения функции из библиотеки? Ведь библиотека — это же откомпилированный код?
Здравствуйте, -n1l-, Вы писали:
N>Добрый вечер. Все никак не могу понять одну банальнейшую вещь в C++. N>Вот хотим мы скомпилировать исполняемый файл. Тут все просто, заголовочные файлы инклудятся в нужное место с объявлениями нужных функций, а мы пяшем от счастья. N>Но что касается библиотек. Как я могу использовать заголовочный файл для подключения функции из библиотеки? Ведь библиотека — это же откомпилированный код?
Это не С++ — это сборка проги.
Заголовочный файл нужен компилятору, чтобы проверить правильность вызова функции: по количеству и типам параметров.
И сгенерировать правильный код вызова.
Потом, когда линкер собирает все в кучу, он обнаруживает, что вызов есть, а функции — нет.
Это ошибка линковки "Неопределенное внешнее имя".
Чтобы это преодолеть, нужно ЛИНКЕРУ указать библиотеку, в которой ваша функция лежит.
А со стандартными он сам разбирается — это уже по умолчанию прописано.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>Это не С++ — это сборка проги. LVV>Заголовочный файл нужен компилятору, чтобы проверить правильность вызова функции: по количеству и типам параметров. LVV>И сгенерировать правильный код вызова.
LVV>Потом, когда линкер собирает все в кучу, он обнаруживает, что вызов есть, а функции — нет. LVV>Это ошибка линковки "Неопределенное внешнее имя". LVV>Чтобы это преодолеть, нужно ЛИНКЕРУ указать библиотеку, в которой ваша функция лежит.
LVV>А со стандартными он сам разбирается — это уже по умолчанию прописано.
Не совсем понял. А что насчет классов? Мне же нужно подключить заголовочный файл описания класса из библиотеки и потом вернуть его из функции которая его создаст.
Здравствуйте, -n1l-, Вы писали:
N>Не совсем понял. А что насчет классов? Мне же нужно подключить заголовочный файл описания класса из библиотеки и потом вернуть его из функции которая его создаст.
Тогда выражайтесь яснее.
Приведите пример, чего хотите-то.
И в какой ОС и в какой версии ОС работаете.
А то в виндах в библиотеках классы напрямую не было возможности прописывать.
Раньше.
Очень часто задаваемый вопрос на форуме был: как в динамическую библиотеку класс запихать.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, -n1l-, Вы писали:
N>Добрый вечер. Все никак не могу понять одну банальнейшую вещь в C++. N>Вот хотим мы скомпилировать исполняемый файл. Тут все просто, заголовочные файлы инклудятся в нужное место с объявлениями нужных функций, а мы пяшем от счастья. N>Но что касается библиотек. Как я могу использовать заголовочный файл для подключения функции из библиотеки? Ведь библиотека — это же откомпилированный код?
в поставке с библиотеками идут заголовочные файлы — их инклюдишь к себе к код,
сами же библиотеки(~откомпилированный код) если они
1) статические(staticlib) или статически загружаемые динамические библиотеки —
то говоришь компилятору подцепить(слинковать) в твой исполняемый файл
2) динамически загружаемые динамические библиотеки —
сам в коде их загружаешь("путь к файлу" в специальную функцию передаешь).
Здравствуйте, -n1l-, Вы писали:
N>Добрый вечер. Все никак не могу понять одну банальнейшую вещь в C++. N>Вот хотим мы скомпилировать исполняемый файл. Тут все просто, заголовочные файлы инклудятся в нужное место с объявлениями нужных функций, а мы пяшем от счастья. N>Но что касается библиотек. Как я могу использовать заголовочный файл для подключения функции из библиотеки? Ведь библиотека — это же откомпилированный код?
Или я не понял вопрос или что еще либо.
Заголовочный файл нужен для объявления имен функций, тут, как ты заметил все просто и мы пляшем от счастья.
Когда дело после компиляции доходит до сборки бинарного файла (екзешника, длл, библиотеки или аналогов под *nix) чем уже заведует линковщик (c++ тут вообще ни коим боком), то надо явно указать путь этого самого "откомпилированного кода"
Тут есть фишка, бывают так называемые "хидер онли" библиотеки, обычно это что-то на шаблонах (на то есть свои причины). Суть этих библиотек в том, что весь код размещен в этих заголовочных файлах и никакие другие файлы не нужны для успешной компиляции и сборки проекта.
В частности в VC++ нередки ситуации когда ты пишешь #include <blablabla.h>, юзаешь в коде функции из этого файла, а проект не собирается.
И спасает директива #pragma comment(lib , "blablabla.lib") (это понятное дело не единственный способ)
То есть прагмой ты указываешь линкеру откуда брать скомпилированный код для объявленных в заголовках функциях.
В чем сложность вопроса я не понял.
Да и вообще, имхо, этот вопрос не для с++, поскольку обсуждаемая проблема касается исключительно линкера.
Здравствуйте, -n1l-, Вы писали:
N>Добрый вечер. Все никак не могу понять одну банальнейшую вещь в C++. N>Вот хотим мы скомпилировать исполняемый файл. Тут все просто, заголовочные файлы инклудятся в нужное место с объявлениями нужных функций, а мы пяшем от счастья.
Не все так просто. Компиляцию C++ можно разбить на два важных для программиста этапа:
1)Превращение C++ кода в объектный файл. Объектный файл это по сути готовый
машинный код, но все места в которых компилятор увидел ссылки на элементы с вшнешней линковкой
он заменил на заглушки. Например, допустим ваш проект состоит из двух файлов foo.cpp и boo.cpp:
После стадии 1 мы получаем foo.o(или foo.obj) с заглушками вместо void boo() и void Boo::boo() и boo.o(boo.obj).
После этого наступает этап два
2)Линковка, вместо компилятор C++ теперь работает линковщик, он берет файл foo.o и boo.o, а также стандартную библиотеку C++
и заменяет заглушки на адрес реальных функций, т.к. у него есть оба файла foo.o и boo.o.
N>Но что касается библиотек. Как я могу использовать заголовочный файл для подключения функции из библиотеки? Ведь библиотека — это же откомпилированный код?
Библиотека это по сути набор уже скомпилированных объектных файлов.
Поэтому с ней даже проще чем с исходниками, ведь вам не нужно для них выполнять стадию 1
P.S.
Стоит пару дней пособирать c++ программы с помощью консоли, чтобы такие вопросы отпали.
Здравствуйте, -n1l-, Вы писали:
N>Добрый вечер. Все никак не могу понять одну банальнейшую вещь в C++. N>Вот хотим мы скомпилировать исполняемый файл. Тут все просто, заголовочные файлы инклудятся в нужное место с объявлениями нужных функций, а мы пяшем от счастья. N>Но что касается библиотек. Как я могу использовать заголовочный файл для подключения функции из библиотеки? Ведь библиотека — это же откомпилированный код?
Вещи действительно простые:
Содержимое заголовочного файла тупо вставляется вместо директивы #include. Никакой *.c или *.cpp при этом не используется.
Библиотека по сути ничем не отличается от простого объектного файла. То есть нет разницы на этапе компиляции, если ты включаешь заголовочный файл от скомпилированной библиотеки или заголовочный файл от своего локального исходника (уже скомпилированного или еще не скомпилированного) — все используемые символы будут разрешаться наьэтапе компоновки, а компоновщик работает с уже откомпилированными файлами (будь то объектники или библиотеки).
Здравствуйте, Evgeniy Skvortsov, Вы писали:
ES>В частности в VC++ нередки ситуации когда ты пишешь #include <blablabla.h>, юзаешь в коде функции из этого файла,
Вот оно! Откуда я могу знать какой заголовок я могу использовать из библиотеки,
если я работаю со скомпилированной сборкой? Он в самой сборке храниться?
Вот этого я никак не могу понять. Беру библиотеку, ок, а откуда берется заголовочный файл? Там же уже скомпилированный код.
Или там, в библиотеке есть особый вид метаданных?
Здравствуйте, -n1l-, Вы писали:
ES>>В частности в VC++ нередки ситуации когда ты пишешь #include <blablabla.h>, юзаешь в коде функции из этого файла, N>Вот оно! Откуда я могу знать какой заголовок я могу использовать из библиотеки,
Из документации к библиотеке, которую предоставляет разработчик этой библиотеки.
Из самой библиотеки тоже можно вытащить имена экспортируемых функций, но тут куча нюансов.
Информация будет неполной (если функция имеет декорированное имя) то можно узнать имя функции и количество и тип параметров.
В противном случае вообще ничего кроме имени функции будет неизвестно.
Так что всегда поставляется минимум 2 файла — заголовочный и сам файл библиотеки.
Здравствуйте, Evgeniy Skvortsov, Вы писали:
ES>Здравствуйте, -n1l-, Вы писали:
ES>>>В частности в VC++ нередки ситуации когда ты пишешь #include <blablabla.h>, юзаешь в коде функции из этого файла, N>>Вот оно! Откуда я могу знать какой заголовок я могу использовать из библиотеки,
ES>Из документации к библиотеке, которую предоставляет разработчик этой библиотеки.
ES>Из самой библиотеки тоже можно вытащить имена экспортируемых функций, но тут куча нюансов. ES>Информация будет неполной (если функция имеет декорированное имя) то можно узнать имя функции и количество и тип параметров. ES>В противном случае вообще ничего кроме имени функции будет неизвестно.
ES>Так что всегда поставляется минимум 2 файла — заголовочный и сам файл библиотеки.
Вообще говоря, три файла —
Сама DLL, содержащая исполняемый код;
h — файл, с сигнатурами функций и объявлениями классов(для C/C++)
и lib — файл, с кодом, который подключает эту DLL.(для линкера)
но надо учесть, что lib — это компиляторозависимая вещь
Здравствуйте, icWasya, Вы писали:
W>Вообще говоря, три файла — W>Сама DLL, содержащая исполняемый код; W> h — файл, с сигнатурами функций и объявлениями классов(для C/C++) W> и lib — файл, с кодом, который подключает эту DLL.(для линкера) W>но надо учесть, что lib — это компиляторозависимая вещь
Ну это в случае динамически подключаемой библиотеки, в случае статически линкуемой будет как раз 2 файла .h и .lib
Да и в случае dll можно имея .h и .dll спокойно юзать библиотеку с помощью GetProcAdress
Нюансов конечно много, но если речь о минимальной поставке — то все таки 2 файла.
Здравствуйте, -n1l-, Вы писали:
N>Но что касается библиотек. Как я могу использовать заголовочный файл для подключения функции из библиотеки? Ведь библиотека — это же откомпилированный код?
Библиотеку нельзя использовать в виде только лишь H-файла (ну, за исключением ряда случаев когда библиотека header-only). Обычно же понадобится как H-файл, так и бинарный LIB-файл (или DLL/SO, если будет внешняя линковка). Если этот бинарник отсутствует, то будут проблемы:
* при линковке — если ожидается LIB
* при запуске — если ожидается DLL/SO
Здравствуйте, Mr.Delphist, Вы писали:
Т.е. в с++ если я делаю библиотеку, то пользователю необходимо поставить кроме библиотеки исходники заголовочных файлов?
Я так понимаю где описаны объявления публичных функций и классов?
Здравствуйте, -n1l-, Вы писали:
N>Т.е. в с++ если я делаю библиотеку, то пользователю необходимо поставить кроме библиотеки исходники заголовочных файлов? N>Я так понимаю где описаны объявления публичных функций и классов?
Да.
Только предлагаю слово "исходники" убрать. В С++ для использования библиотек в общем случае нужны заголовочные файлы.
Здравствуйте, -n1l-, Вы писали:
N>Т.е. в с++ если я делаю библиотеку, то пользователю необходимо поставить кроме библиотеки исходники заголовочных файлов? N>Я так понимаю где описаны объявления публичных функций и классов?
Именно. А саму либу — желательно представить в разных видах сборки (дебажная/релизная, статическая/динамическая и т.п.)
Здравствуйте, Evgeniy Skvortsov, Вы писали:
ES>Ну это в случае динамически подключаемой библиотеки, в случае статически линкуемой будет как раз 2 файла .h и .lib
ES>Да и в случае dll можно имея .h и .dll спокойно юзать библиотеку с помощью GetProcAdress
ES>Нюансов конечно много, но если речь о минимальной поставке — то все таки 2 файла.
Во многих коммерческих dll бывает "статическая часть", какой-то код, который влинковывается прямо в использующий dll модуль. Обычно он сидит в той самой .lib...
А так, ты уже сам упомянул теоретически минимальную поставку -- один хедер и всё...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Mr.Delphist, Вы писали:
MD>Именно. А саму либу — желательно представить в разных видах сборки (дебажная/релизная, статическая/динамическая и т.п.)
Одноъ и много-поточная, с встроенны crt и с внешним и т. д...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском