Как создать 64 разделяемую 64-битную совместимую с Linux библиотеку (* .so) для кода C ++ - PullRequest
2 голосов
/ 09 марта 2012

Мое требование - работать с некоторыми интерфейсными .h файлами. Прямо сейчас у меня есть файлы .h и .cpp / .cc в моем проекте.

Мне нужно скомпилировать ее в общую 64-битную совместимую с Linux библиотеку (* .so), используя NetBeans / Eclipse в Linux Fedora.

Ответы [ 2 ]

3 голосов
/ 09 марта 2012

Поскольку условные обозначения GCC C ++ ABI немного изменились (в частности, из-за эволюции стандартных библиотек C ++ или соглашения об искажении имен) от одной версии GCC к другой (например, от g++-4.4 до g++-4.6), ваша общая библиотека может бытьзависит от версии g++, использованной для его сборки

(На практике изменения в g ++ часто бывают небольшими, поэтому на вас это может не повлиять)

ЕслиВы хотите, чтобы символ был общедоступным с dlsym . Желательно объявить его extern "C" в заголовочных файлах (в противном случае вам следует указать его имя ).как создать разделяемую библиотеку, прочитайте документацию, например Program Library Howto .

См. также этот вопрос

И я предлагаю создать ваши совместно используемые библиотеки собычные инструменты командной строки (например, Makefile -s).Не полагайтесь на сложные IDE, такие как NetBeans / Eclipse, для их создания (они все равно вызывают утилиты командной строки).

2 голосов
/ 07 апреля 2012

Если вы компилируете библиотеку из 3 исходных файлов C ++ с именами a.cc, b.cc и c.cc соответственно;


g++ -fpic -Wall -c a.cc

g++ -fpic -Wall -c b.cc

g++ -fpic -Wall -c c.cc

g++ -shared -Wl,-soname,libmylib.so.0 -o libmylib.so.0.0.0 a.o b.o c.o

Затем вы устанавливаете библиотеку с помощью ldconfig, см.

man 8 ldconfig

Затем вы можете скомпилировать программу, которая использует библиотеку, следующим образом (, но обязательно указывайте префикс extern "C" перед объявлениями классов в заголовочных файлах, включенных в исходный код, с использованием библиотеки.)

g ++ -o myprog main.cc -lmylib

Я попробовал эти варианты компиляции с моим собственным примером кода, и все прошло успешно.

В основном То, что описано в Общие библиотеки относится к C ++, просто замените gcc на g ++.

Теория, лежащая в основе всего этого, такова;

Библиотеки загружаются динамически при первой загрузке программы, что можно подтвердить, выполнив трассировку системного вызова в работающей программе, например, strace -o trace.txt ls, который выведет список системных вызовов, которые программа сделала во время выполнения, в файл с именем trace.txt. В верхней части файла вы увидите, что программа (в данном случае ls) действительно отобразила все библиотеки в память.

Поскольку библиотеки загружаются динамически, во время компоновки неизвестно, где код библиотеки будет существовать в виртуальном адресном пространстве программы во время выполнения. Поэтому библиотечный код должен быть скомпилирован с использованием кода, независимого от позиции - следовательно, опция -fpic, которая указывает этапу трансляции генерировать код сборки, который был закодирован с учетом кода, независимого от позиции. Если вы скажете gcc/g++ остановиться после этапа перевода с помощью параметра -S (в верхнем регистре S), а затем посмотрите на полученный файл '.s', один раз с параметром -fpic и один раз без, вы получите увидеть разницу (т. е. динамический код имеет @GOTPCREL и @PLT, по крайней мере, для x86_64).

Разумеется, компоновщику необходимо связать все типы перемещаемых объектов ELF с исполняемым кодом, подходящим для использования в качестве разделяемой библиотеки Linux.

...