Свяжите две библиотеки друг с другом - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть функция в libA.so, которая используется в libB.so, И функция в libB.so, которая используется в libA.so! Поэтому я не могу скомпилировать ни одну из этих библиотек. Как я могу скомпилировать эти две библиотеки? Должен ли я использовать третью библиотеку и переместить зависимости в эту библиотеку? Я использовал qt и c ++

Обновлен: в компиляции libA.so ошибка get не может найти libB.so, а в libB.so ошибка get не может найти libA.so

Ответы [ 4 ]

0 голосов
/ 11 сентября 2018

У меня есть функция в libA.so, которая используется в libB.so, и функция в libB.so, которая используется в libA.so!

Это неправильный дизайн . Библиотека не может даже косвенно зависеть от себя. Такая округлость является признаком чего-то очень неправильного, и вы неправильно понимаете, что такое библиотека программного обеспечения (это больше, чем случайная коллекция функций или объектных файлов; она должна быть как-то «программным модулем» и связана с ней). модульное программирование и часто определяет и реализует полностью набор связанных абстрактных типов данных ).

Итак, выбросить libA.so и libB.so прочь . И создает одиночный libAB.so, содержащий весь код, который вы поместили в совместно используемые объекты libA.so и libB.so (а не в подлинные библиотеки).

Ответ от nm дает технический способ решения вашей проблемы, но в глубине души ваш дизайн ошибочен, и вы злоупотребляете библиотеками (и вы не можете назвать свою libA или libB библиотекой , даже если вы создали их как общий объект в ELF ).

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

Чтение Библиотека программ HowTo и Drepper's Как писать общие библиотеки бумага для более.

0 голосов
/ 10 сентября 2018

БОЛЬШОЙ ОТКАЗ ОТ ЖИРА Делайте это только в случае крайней необходимости. Предпочтительным способом является рефакторинг структуры вашего проекта таким образом, чтобы она не содержала циклы зависимостей.

При создании разделяемой библиотеки компоновщику вообще не нужно знать о других разделяемых библиотеках. Можно использовать их в командной строке, но это необязательно. Пример:

// libA.cpp
extern void funcB();
void funcA() {
    funcB();
}

Компиляция и ссылка:

g++ -fPIC -c libA.cpp
g++ -shared -o libA.so libA.o

funcB должен жить в libB.so, но мы не сообщаем компоновщику, где его найти. Символ просто остается неопределенным в libA.so и будет (надеюсь) разрешен в время загрузки .

// libB.cpp
extern void funcA();
void funcB() {
   funcA();
}

Компиляция и компоновка, теперь явно использующие libA.so (игнорируйте бесконечную рекурсию, это всего лишь пример):

g++ -fPIC -c libB.cpp 
g++ -shared -o libB.so libB.o -L/where/libA/is -lA

Теперь исполняемый файл должен загружать libB.so перед загрузкой libA.so, иначе libA.so не может быть загружен. Это легко сделать (просто связать исполняемый файл только с libB.so, а не libA.so), но иногда это может быть неудобно. Таким образом, можно повторно связать libA.so после building libB.so:

g++ -shared -o libA.so libA.o -L /where/libB/is -lB

Теперь можно связать исполняемый файл с libA или libB, а другой будет выбран автоматически.

0 голосов
/ 11 сентября 2018

Наконец-то я это решаю.Как сказал @nm, нам не нужно связывать libA.so и libB.so во время компиляции, поэтому я удаляю -lA и -lB при их сборке, и я не получил никакой ошибки.И в приложении, которое хочет использовать libA.so или libB.so, я связал их с -lA или -lB.Так что это работает правильно.

0 голосов
/ 10 сентября 2018

Это кажется немного проблематичным для повторного использования в будущем, возможно, вы захотите либо по-разному разделить ваши функции между этими библиотеками, либо создать третью, которая содержит все функции "инструмента", чтобы иметь функции LibA и libB друг без друга.

...