Разрешены ли ссылки на файлы .o при создании статической библиотеки? - PullRequest
0 голосов
/ 12 июня 2019

Например, допустим, я создаю библиотеку a.lib, в которой есть два файла: foo.c и bar.c.foo.c вызывает функцию void bar(), определенную в bar.c.

Теперь предположим, что у меня есть исполняемый файл, который я собираюсь создать, который имеет два файла: main.c и bar.c.В этом bar.c также определено void bar(), но с другой реализацией.

Когда я связываю исполняемый файл с a.lib, который void bar() будет вызываться из исполняемого файла?

1 Ответ

1 голос
/ 12 июня 2019

Предположим, что:

  1. Библиотека libfoobar.a (или libfoobar.lib) и находится в каталоге ./lib.
  2. Файл библиотеки foo.c определяет foo() и foo(), вызывает bar().
  3. Файл библиотеки bar.c определяет bar().
  4. Исходные файлы библиотеки не находятся в текущем каталоге.
  5. Файл программы bar.c также определяет bar() - другая реализация.
  6. Файл программы main.c вызывает как foo(), так и bar().
  7. Ваша командная строка ссылки выглядит так:

    cc -o program main.o bar.o -L ./lib -lfoobar
    

Тогда:

  • Программа будет содержать bar() из программного файла bar.c (потому что он был явно включен в командную строку перед библиотекой).
  • Программа будет содержать foo() из файла библиотеки foo.c, но bar(), который она вызывает, будет из файла программы bar.c, а не из библиотеки.

Если задействовано больше символов, так что библиотека foo.c вызывает функции, которые доступны только в библиотеке bar.c (программа bar.c не реализует все эти функции), то соединение не будет выполнено, поскольку Программа содержит bar.c программы (безоговорочно), но ей также нужен bar.c библиотеки, но это дает вам двойное определение функции bar() - что является ошибкой.

Повороты могут стать серьезными. Простое правило - не делай этого. То есть не заставляйте программу bar.c предоставлять символ, который также доступен в библиотеке bar.c. Если вы должны и есть другие точки входа, то вам придется работать намного усерднее.

Не помещайте библиотеки перед объектными файлами; тогда вы ошибетесь с bar(), определенным вдвойне. Библиотеки идут после объектных файлов в списке ссылок. Однако вам нужно получить несколько (статических) библиотек в правильном порядке. Или используйте специальные опции для повторного сканирования загрузчиком библиотек и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...