Статическое и динамическое связывание библиотек

StackOverflow https://stackoverflow.com/questions/168979

  •  05-07-2019
  •  | 
  •  

Вопрос

В 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, из-за которой вы получаете соответствующую ошибку.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top