Статическое и динамическое связывание библиотек
Вопрос
В C ++ статическая библиотека A связана с динамическими библиотеками B и C. Если в A используется класс Foo, определенный в B, будет ли C связываться, если он не использует Foo?
Я думал, что ответ был да, но сейчас я столкнулся с проблемой с xlc_r7, где библиотека C говорит, что Foo является неопределенным символом, что касается C. Моя проблема в том, что библиотека C не использует класс, ссылающийся на нее. Это ссылки в Win32 (VC6) и OpenVMS.
Это расхождение компоновщика или PBCAK?
Новая информация:
<Ол>B зависит от C, но не наоборот.
Я не использую / OPT: REF для ссылки в Windows, и она ссылается без проблем. Р>
Решение
Когда вы статически связываете, два модуля становятся одним. Таким образом, когда вы компилируете C и связываете в него A, создается впечатление, что вы скопировали весь исходный код A в исходный код C, а затем скомпилировали объединенный исходный код. Таким образом, C.dll включает A, который зависит от B через Foo. Вам нужно будет связать C с библиотекой ссылок B, чтобы удовлетворить эту зависимость.
Обратите внимание, что согласно вашей информации, это создаст круговую зависимость между B и C.
Другие советы
Похоже, что это, вероятно, компоновщик (ld / unix), так как (большинство версий, которые я использовал) ld связывает библиотеки слева направо - и если в первой есть ссылка, которая требуется для позже обычная уловка - добавить первую библиотеку (или любую необходимую библиотеку) в конец команды.
Попробуйте и посмотрите ....
Ваша строка ссылок для C включает в себя экспортную библиотеку для B? Если так, то, как предполагает Ричард, это звучит как упорядоченность.
Еще одно предложение - посмотреть, есть ли опция компоновщика, чтобы игнорировать символы, на которые нет ссылок, если C не нужна эта функциональность от A. Для компоновщика Microsoft это достигается с помощью ключа / OPT: REF.
Единственная причина, по которой C не будет ссылаться, заключается в том, что компилятор считает, что действительно нужен символ Foo.
Поскольку C не ссылается на символы Foo, должна быть еще одна причина, почему компоновщику нужен символ.
Единственная другая причина, о которой я знаю, это какой-то экспорт. Я знаю только Visual C ++, поэтому я предлагаю вам найти какой-то эквивалент __declspec (dllexport)
в предварительно обработанных файлах и посмотреть, что его генерирует.
Вот что я хотел бы сделать: сохранить результаты препроцессора в отдельном файле и найти их в Foo. Либо это будет происходить как экспорт, либо компилятор ссылался на него каким-либо образом.
Если определение конкретной функции не требуется, то эта библиотека не будет связана на этапе компоновки. В вашем случае, поскольку определение foo присутствует в библиотеке B, а не в библиотеке C. Таким образом, библиотека C не будет загружаться в память при загрузке исполняемого файла.
Но, похоже, вы используете функцию foo () и в библиотеке C, из-за которой вы получаете соответствующую ошибку.