2008-10-03 2 views
2

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

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

Является ли это несоответствием компоновщика или PBCAK?

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

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

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

+0

согласно msdn, LINK по умолчанию удаляет неупорядоченные упакованные функции (как если бы вы использовали/OPT: REF). – xtofl 2008-10-04 18:49:20

ответ

4

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

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

0

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

это попробовать и посмотреть ....

+0

Компоновщик xlc более сложный, хотя ... Линия ссылок слева направо будет работать в основном, но эффективно все загружается в память, а затем выполняется графическое перемещение, чтобы удовлетворить ссылку. Это дороже, чем ссылка старого стиля, но ссылку не нужно заказывать. Это также ломается веселыми способами. – 2008-10-04 01:01:56

+0

Я не думаю, что это проблема, потому что 1. Я пробовал другой порядок и 2. Foo не используется ни одной из других библиотек. – Jake 2008-10-05 03:45:57

0

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

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

0

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

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

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

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

0

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

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

Смежные вопросы