Конфликты статических и общих библиотечных символов? - PullRequest
6 голосов
/ 07 февраля 2010

У меня есть проект, работающий над этим, использующий FreeImage и openCV, в настоящее время мы используем поддержку jpeg от обоих из них (я работаю над исправлением этого, но сейчас он должен остаться). В любом случае FreeImage компилирует libjpeg 7.0 в свои статические библиотеки, а библиотека highCi openCV связывает ее как общую библиотеку (в моей системе, Ubuntu 9, у меня установлен libjpeg 6.2).

Они ссылаются на конечную библиотеку, которая используется для связи с различными программами, java-обертками и т. Д. Все это прекрасно работает, никаких конфликтов символов или чего-либо еще во время компиляции / компоновки. Однако когда я открываю изображение с помощью функции openCV cvLoadImage, оно умирает при чтении заголовка, скорее всего из-за различий между заголовками в 6.2 и 7.0.

Если я отсоединяю FreeImage (и закомментирую код, который требует этого), вызовы openCV снова начинают работать, поэтому очевидно, что статические символы libjpeg из FreeImage конфликтуют с символами, которые будут загружены из общей библиотеки libjpeg. Я не могу понять, почему мой компилятор не выдает ошибку во время компоновки из-за двух наборов символов libjpeg. Кроме того, я попытался временно заменить заголовок jpeglib.h моей системы версией 7.0, чтобы посмотреть, будет ли скомпилированная с этим openCV синхронизироваться с символами, которые freeimage вносит в таблицу, но безрезультатно.

Наконец, я поместил printf в jpeg_read_header в libjpeg, который компилирует freeimage, и перестроил его, чтобы посмотреть, использует ли openCV определение libipeg freeimage. Он не распечатывался, поэтому я должен предположить, что нет.

Так что я думаю, мои вопросы

1) Почему связывание статического libjpeg и общего libjpeg не приводит к ошибкам связывания из-за дублирования символов?

2) Кто-нибудь знает, почему эти две вещи противоречат друг другу?

Редактировать: Компиляция openCV в режиме отладки, а затем в обычном режиме снова, кажется, сбила что-то и заставила его работать снова, не зная, что происходит.

Ответы [ 3 ]

2 голосов
/ 28 мая 2010

Вам нужно изменить параметры связывания, чтобы экспортировать только те символы, которые вы хотите, тогда все конфликтующие символы будут скрыты внутри статической ссылки, а затем конфликтов не будет. По умолчанию все символы экспортируются, вот в чем проблема. Смотрите эту ссылку: http://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html

1 голос
/ 07 февраля 2010

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

Это, кстати, НЕ относится к объектным файлам. Каждый компоновщик, которого я когда-либо использовал, предполагает, что вы хотите использовать все объекты, которые вы укажете, и будете жаловаться, если более одного имеют один и тот же символ.

1 голос
/ 07 февраля 2010

это так

Статические библиотеки компилируются, динамические библиотеки загружаются во время выполнения, но только те символы, которые отсутствуют (я думаю). вы можете скомпилировать совместно используемые библиотеки, и тогда вы, вероятно, получите столкновение символов.

поэтому opencv использует символы, которые скомпилированы, поскольку они уже представлены, а не из динамических библиотек. в конечном итоге вы используете статические символы, возможно с разными сигнатурами, от перспективы opencv.

...