Это продолжение компиляции Dynamic Shared Library с g ++ .
Я пытаюсь создать общую библиотеку классов на C ++ в Linux. Я могу заставить библиотеку компилироваться, и я могу вызывать некоторые (не классовые) функции, используя учебники, которые я нашел здесь и здесь . Мои проблемы начинаются, когда я пытаюсь использовать классы, которые определены в библиотеке. Второй учебник, на который я ссылался, показывает, как загрузить символы для создания объектов классов, определенных в библиотеке, но не использует эти объекты для выполнения какой-либо работы.
Кто-нибудь знает более полный учебник для создания общих библиотек классов C ++, который также показывает, как использовать эти классы в отдельном исполняемом файле? Очень простое руководство, которое показывает создание объектов, их использование (простые методы получения и установки вполне подойдут) и удаление будет фантастическим. Ссылка или ссылка на некоторый открытый исходный код, который иллюстрирует использование разделяемой библиотеки классов, была бы одинаково хороша.
Хотя ответы от codelogic и nimrodm действительно работают, я просто хотел добавить, что я поднял копию Beginning Linux Programming после того, как задал этот вопрос, и в его первой главе приведен пример кода C и хорошие объяснения для создания и использования статических и разделяемых библиотек. , Эти примеры доступны в Поиске книг Google в более старом издании этой книги .
источник
Ответы:
myclass.h
myclass.cc
class_user.cc
В Mac OS X скомпилируйте с:
В Linux скомпилируйте с:
Если бы это было для системы плагинов, вы бы использовали MyClass в качестве базового класса и определяли бы все необходимые виртуальные функции. Затем автор плагина наследует MyClass, переопределяет виртуалы и реализует
create_object
иdestroy_object
. Ваше основное приложение не должно быть изменено каким-либо образом.источник
extern "C"
потому чтоdlsym
функция является функцией C. И для динамической загрузкиcreate_object
функции она будет использовать связь в стиле C. Если бы вы не использовалиextern "C"
, не было бы способа узнать имяcreate_object
функции в файле .so из-за искажения имени в компиляторе C ++.Ниже приведен пример совместно используемой библиотеки классов. [H, cpp] и модуля main.cpp с использованием библиотеки. Это очень простой пример, и make-файл может быть сделан намного лучше. Но это работает и может помочь вам:
shared.h определяет класс:
shared.cpp определяет функции getx / setx:
main.cpp использует класс,
и make-файл, который генерирует libshared.so и связывает main с разделяемой библиотекой:
Для фактического запуска 'main' и соединения с libshared.so вам, вероятно, потребуется указать путь загрузки (или поместить его в / usr / local / lib или аналогичный).
Далее указывается текущий каталог в качестве пути поиска для библиотек и запускается main (синтаксис bash):
Чтобы увидеть, что программа связана с libshared.so, вы можете попробовать ldd:
Печать на моей машине:
источник
-L. -lshared -Wl,-rpath=$$(ORIGIN)
при связывании и отбросьте этоLD_LIBRARY_PATH=.
.По сути, вы должны включить заголовочный файл класса в код, где вы хотите использовать класс в общей библиотеке. Затем, когда вы ссылаетесь, используйте флаг '-l', чтобы связать ваш код с разделяемой библиотекой. Конечно, для этого требуется, чтобы .so находился там, где его может найти ОС. Смотрите 3.5. Установка и использование общей библиотеки
Использование dlsym предназначено для случаев, когда вы не знаете во время компиляции, какую библиотеку вы хотите использовать. Это не похоже на случай здесь. Может быть, путаница заключается в том, что Windows вызывает динамически загружаемые библиотеки независимо от того, выполняете ли вы компоновку во время компиляции или во время выполнения (аналогичными методами)? Если это так, то вы можете думать о dlsym как о эквиваленте LoadLibrary.
Если вам действительно нужно динамически загружать библиотеки (т.е. они являются подключаемыми модулями), тогда этот FAQ должен помочь.
источник
Вдобавок к предыдущим ответам я хотел бы повысить осведомленность о том, что вы должны использовать идиому RAII (Resource Acquisition Is Initialisation), чтобы быть уверенным в уничтожении обработчика.
Вот полный рабочий пример:
Объявление интерфейса
Interface.hpp
:Содержимое общей библиотеки:
Динамический обработчик общей библиотеки
Derived_factory.hpp
::Код клиента:
Примечание:
.hpp
и.cpp
файлы.new
/delete
перегрузку.Две понятные статьи, чтобы получить больше деталей:
источник