#c #windows #g #static-libraries #static-linking
#c #Windows #g #статические библиотеки #статическое связывание
Вопрос:
main.cpp
#include <iostream>
int main() {
std::cout << "main()" << std::endl;
foo();
return 0;
}
foo.cpp
#include <iostream>
extern "C" {
void foo() {
std::cout << "bar" << std::endl;
}
}
Скомпилировать статическую библиотеку:
$ g foo.cpp -static
Ошибка:
undefined reference to `WinMain'
Но это компилирует:
$ g foo.cpp -shared -o foo.lib
Теперь у меня есть статическая библиотека с именем foo.lib
(предположительно).
Я пытаюсь скомпилировать исполняемый файл, который ссылается на него:
$ g -L -lfoo main.cpp -o main.exe
И получите эту ошибку:
'foo' was not declared in this scope
Но foo
объявлено в статической библиотеке, с которой я связываюсь. Если ссылка работает, я не думаю, что мне нужно объявлять ее в main.cpp также. Так почему же ссылка не работает?
Обновить.
Я добавил void foo();
в main.cpp так что он не жалуется на то, что foo
нужно объявить.
#include <iostream>
void foo();
int main() {
std::cout << "main()" << std::endl;
foo();
return 0;
}
Итак, я пытаюсь скомпилировать снова и получаю эту новую ошибку:
undefined reference to `foo()'
Зачем мне нужно определять foo
в main.cpp ? Это уже определено в foo.cpp это статическая библиотека.
Если мне нужно определить foo
в main.cpp это сводит на нет всю цель ссылки на библиотеку foo.lib.
Обновления
- Удаление всех
extern "C" {
…}
строки не устраняют ошибки «неfoo
определено».
Комментарии:
1. Функция должна быть объявлена при вызове этой функции. Вот как работает C . Компилятор должен знать имя функции и типы всех параметров. Связывание происходит после компиляции. Сначала код должен быть скомпилирован.
2. Всем, кто проголосовал за закрытие, пожалуйста, удалите свою учетную запись. Я написал очень четкий вопрос с минимальными воспроизводимыми примерами.
3. @SamVarshavchik Я объявил
foo
в начале main.cpp (смотрите Мой обновленный пост) но теперь он жалуется, чтоfoo
это не определено. Если мне нужно определитьfoo
в main.cpp это сводит на нет цель установления связей.4. Нет, это не «противоречит цели связывания». Привязка к библиотеке не устраняет необходимости объявлять функции. Вот почему все часто используемые библиотеки поставляются с заголовочными файлами, которые объявляют все функции в библиотеке. Если акт связывания с библиотекой устраняет необходимость объявлять какие-либо функции в библиотеке, тогда не было бы необходимости иметь заголовочные файлы, не так ли? И поскольку в библиотеке
foo()
определяется с помощью ссылки «C», то объявление, в которое вы добавилиmain.cpp
, тоже должно иметь ссылку «C», верно?5. Я объявил функцию, как вы предложили в своем первом комментарии. Теперь он жалуется, что он не определен. Я согласен с объявлением его в main.cpp . Я не согласен с ее определением в main.cpp ; определяющий
foo
в обоих main.cpp и foo.cpp противоречит назначению статической библиотеки foo.cpp .
Ответ №1:
Далее следуют магические заклинания, которые вы ищете:
- main.cpp
#include <iostream>
extern void foo();
int main() {
std::cout << "main()" << std::endl;
foo();
}
- foo.cpp
#include <iostream>
void foo() {
std::cout << "bar" << std::endl;
}
Консольные команды:
$ g -o foo.obj -c foo.cpp
$ ar rcs foo.lib foo.obj
$ g main.cpp foo.lib -o main.exe
Эти заклинания вызывают в воображении статическую библиотеку foo с исполняемым файлом main, статически связанным с ним.