Статическое и динамическое связывание библиотек - PullRequest
2 голосов
/ 04 октября 2008

В C ++ статическая библиотека A связана с динамическими библиотеками B и C. Если в A используется класс Foo, определенный в B, будет ли C связываться, если он не использует Foo?

Я думал, что ответ был да, но сейчас я столкнулся с проблемой с xlc_r7, где библиотека C говорит, что Foo является неопределенным символом, что касается C Моя проблема в том, что библиотека C не использует класс, ссылающийся на нее. Это ссылки в Win32 (VC6) и OpenVMS.

Это расхождение компоновщика или PBCAK?

Новая информация:

  1. B зависит от C, но не наоборот.

  2. Я не использую / OPT: REF для связи в Windows, и она связывается без проблем.

Ответы [ 5 ]

4 голосов
/ 04 октября 2008

Когда вы статически связываете, два модуля становятся одним. Таким образом, когда вы компилируете C и связываете в него A, создается впечатление, что вы скопировали весь исходный код A в исходный код C, а затем скомпилировали объединенный исходный код. Таким образом, C.dll включает A, который зависит от B через Foo. Вам нужно будет связать C с библиотекой ссылок B, чтобы удовлетворить эту зависимость.

Обратите внимание, что согласно вашей информации, это создаст круговую зависимость между B и C.

0 голосов
/ 10 марта 2017

Если определение конкретной функции не требуется, то эта библиотека не будет связана во время фазы соединения. В вашем случае определение foo присутствует в библиотеке B, а не в библиотеке C. Таким образом, библиотека C не будет загружаться в память при загрузке исполняемого файла.

Но, похоже, вы используете функцию foo () и в библиотеке C, из-за которой вы получаете соответствующую ошибку.

0 голосов
/ 04 октября 2008

Единственная причина, по которой C не будет ссылаться, заключается в том, что компилятор считает, что нужен символ Foo.

Так как C не относится к символам Foo, должна быть еще одна причина, почему компоновщику нужен символ.

Единственная другая причина, о которой я знаю, это какой-то экспорт. Я знаю только Visual C ++, поэтому я предлагаю вам найти какой-то эквивалент __declspec( dllexport ) в предварительно обработанных файлах и посмотреть, что его генерирует.

Вот что я хотел бы сделать: сохранить результаты препроцессора в отдельном файле и найти их в Foo. Либо это будет происходить как экспорт, либо компилятор ссылался на него каким-то образом.

0 голосов
/ 04 октября 2008

Является ли ваша строка ссылок для C включающей экспорт lib для B? Если так, то, как предполагает Ричард, это звучит как упорядоченность.

Еще одно предложение - посмотреть, есть ли опция компоновщика, чтобы игнорировать символы, на которые нет ссылок, если C не требует этой функциональности от A. Для компоновщика Microsoft это достигается с помощью ключа / OPT: REF.

0 голосов
/ 04 октября 2008

Звучит так, как будто это, вероятно, компоновщик (ld / unix), так как (большинство версий, которые я использовал) ld связывает библиотеки слева направо - и если в первой есть ссылка, которая требуется для позже обычная хитрость - добавить первую библиотеку (или любую необходимую библиотеку) в конец команды.

Попробуй и посмотри ....

...