gcc, связывающий разделяемую библиотеку, работает, но dlopen той же разделяемой библиотеки терпит неудачу - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть проект, который выглядит так:

executable
    \---> bsp.so
           |---> bsp_protobuf.a
           \---> protobuf.a

Там, где сначала создаются две статические библиотеки (две библиотеки protobuf), которые статически связаны с разделяемой библиотекой bsp.so. И, наконец, bsp.so связывается с исполняемым файлом.

Когда я связываю исполняемый файл и связываю bsp.so, используя gcc в командной строке, он связывается нормально.

Однако, если я не связываю bsp.so, то он также прекрасно работает - это сделано специально - потому что я хочу использовать dlopen(), чтобы определить, нужна мне эта библиотека или нет (у меня есть указатели на объекты, но ни один из которых не создан, и т.д. ...).

Проблема, с которой я столкнулся, заключается в том, что при использовании dlopen() (в коде) библиотека не открывается из-за неопределенного символа. Данный символ находится в статических библиотеках.

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

У меня есть 3-4 другие общие библиотеки, которые я могу успешно использовать dlopen(), поэтому я знаю, что мой общий процесс использования dlopen() хорош.

Я использую dlerror() для вывода неопределенного сообщения об ошибке символа.

Я просмотрел следующие ссылки:

как к силе-символов-с-а-статической библиотеки-к-быть-включено-в-разделяемой библиотеки-бу

как к применить-fvisibility-вариант к символам-в-статических библиотек

Я связал идею -Wl,--whole-archive, но это, похоже, слишком сильно затянулось, и сборка не удалась с таким большим количеством предупреждений - вероятно, что-то большее, связанное с google protobuf, плюс я не уверен, что такой подход мне нужен в итоге.

Я проверил, что моя общая библиотека была построена с -fPIC, я не уверен, что статические библиотеки созданы с -fPIC или они должны быть?

Я тоже посмотрел здесь:

libtool_9.html

, в котором обсуждается, как связать с dlopen(), но это использует libtools - у нас этого нет для всех наших целей, поэтому я не хочу использовать libtools.

Я действительно не уверен, какой путь прогресса - кажется, что это где-то должно быть простое исправление - но, как я говорю, я не могу понять, почему один метод работает, а другой нет ...

Update

Итак, после комментария Сэма я начал искать в правильном месте. Оказывается, make-файл для bsp.so статически связывает только одну из двух библиотек. Существует отдельный тестер для этой общей библиотеки, который связывает обе библиотеки (и поэтому тестер работает), и у меня не было причин подозревать, что библиотека была сломана ... ну, я довольно много узнал о dlopen и связывании и т.д ...: o

1 Ответ

1 голос
/ 03 апреля 2019

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

Когда вы связываете разделяемую библиотеку, необязательно, чтобы все неразрешенные символы из самой разделяемой библиотеки были разрешены любой другой разделяемой библиотекой, с которой она связывается; поэтому, когда вы связываете общую библиотеку, возможно получить неразрешенные символы из самой общей библиотеки.

Соединение исполняемого файла с разделяемой библиотекой происходит успешно, поскольку все неразрешенные символы в исполняемом файле разрешаются совместно используемой библиотекой; но исполняемый файл не загрузится из-за неразрешенных ссылок на символы из самой общей библиотеки. Кроме того, dlopen () при использовании разделяемой библиотеки выдает ту же ошибку.

Страница справочника dlopen также описывает несколько дополнительных флагов, которые можно использовать для управления этим поведением.

...