В программировании C я думал, что объектный файл может быть успешно связан с .so файлом, пока .so файл предлагает все символы, которые были объявлены в заголовочном файле.
Предположим, что у меня есть foo.c, bar.h и две библиотеки libbar.so.1 и libbar.so.2. Реализация libbar.so.1 и libbar.so.2 полностью отличается, но я думаю, что это в порядке пока они оба, функции предложений объявили в bar.h.
Я связал foo.o с libbar.so.1 и произвел исполняемый файл: foo.bin. Этот исполняемый файл работал, когда libbar.so.1 находится в LD_LIBRARY_PATH. (конечно, символьная ссылка сделана как libbar.so), Однако, когда я изменяю символьную ссылку на libbar.so.2, foo.bin не мог работать и complainted это:
undefined symbol: _ZSt4cerr
libbar.so.1 является созданной библиотекой C++, в то время как libbar.so.2 является созданной библиотекой c. Я не понимаю, почему foo.bin нужны те связанные с C++ символы, только значимые в самом libbar.so.1, так как foo.bin создается на чистом foo.c кода c.
_ZSt4cerr - это, очевидно, искаженное имя C++. Возможно, вам нужно проверить, используете ли вы правильный компилятор (gcc/g++, знаю, звучит глупо, но я столкнулся с такой путаницей ;) ), и есть ли в файле bar.h макросы, которые могли бы ссылаться на cerr.
Перед поиском вы должны распутать имя c++. Для gcc есть утилита c++filt:
$ c++filt
_ZSt4cerr
std::cerr
Это просто стандартный поток файлов ошибок.
Вы, вероятно, просто забыли связать всю программу со стандартной библиотекой C ++.
Утверждение в вопросе просто неверно. Вы говорите «заголовочный файл». Не существует такой вещи, как « (единственный) заголовочный файл». Если вы имеете в виду «заголовочный файл, объявляющий определенный класс C ++», то этот класс может быть унаследован от других классов. Или он может использовать исключения. Или RTTI. В этом случае по умолчанию .so, содержащий код, который идет с ним, будет содержать «висящие неопределенные символы». По умолчанию ожидается, что «основная» программа написана на C ++ и связана со средой выполнения C ++.
Возможно создать самодостаточный .so, но вам придется проделать дополнительную работу, чтобы создать его. Возможно, вам потребуется использовать -Bsymbolic
или указать некоторые библиотеки -l при компоновке, или и то, и другое. Эта область плохо документирована и, как правило, требует некоторой археологии.