![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() |
Iron Bug |
![]() ![]()
Сообщение
#1
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Можно ли такое реализовать?
Допустим, есть примерно такой код (собираю под под MinGW): В основном модуле:
В загружаемой динамической библиотеке:
Идея в том, чтобы в основном модуле был базовый класс Base со всеми причиндалами (туда же компилится и его код). А в подгружаемых через LoadLibrary (и заранее неизвестных) библиотеках - дополнительные классы-наследники Derived , которые бы вызывали конструкторы/деструкторы базового класса, а сами были бы экспортируемыми, чтобы основной модуль мог их загружать и использовать. Копаю-копаю, и вот ну никак! При такой реализации вроде бы должно работать, но линкер при сборке dll (__DLL при этом определён) вопит, что декорированное имя импорта конструктора базового класса не определено. Вообще, теоретически, все базовые классы экспортируемого класса тоже должны быть экспортируемыми. Ну, я пыталась добавить в Base ещё и dllexport, но не проканало. То ли неправильно добавляла, то ли это вообще компилятор не жрёт. Он не ругается на такой двойной import-export, но и ошибка не исчезает. Сообщение отредактировал Iron Bug - 14.2.2011, 9:57 |
|
|
![]() |
Iron Bug |
![]()
Сообщение
#2
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Я тут обнаружила потребность народа в некотором примере насчёт использования динамических библиотек.
Вот, вытащила из своего проекта куски, относящиеся к загрузке и вызовам. Смысл примера такой: есть приложение, которое грузит (динамически) библиотеки с некоторым интерфейсом (IInterface). Все загружаемые библиотеки наследуют некоторое дефолтное поведение от базового класса (Base). Если библиотека не реализует какой-то метод интерфейса, то будет вызван базовый метод. Это чтобы не переписывать в каждой библиотеке одни и те же действия. Пример загружаемой библиотеки - Derived. Я привела флаги компиляции и сборки для разных систем (я собираю под линюксом с gcc и icc и под вендой с mingw). Вроде ничего не забыла, но возможно, что некоторые флаги не нужны для данного примера (я их поместила в квадратные скобки [...]). Просто у меня проект большой и там много чего ещё кроме этого, поэтому там могли оказаться не относящиеся к данной подзадаче параметры. Да, стандартные флаги для библиотек типа -ldl я сюда не выписывала. Выписаны только специфические параметры. Какие плюсы? Собственно, независимость библиотек от основного кода. Для добавления функционала достаточно перекомпилять загружаемые модули. Базовый функционал класса Base можно менять, не пересобирая библиотеки, которые его используют. Надеюсь, что в принципе понятно. Общий файл интерфейса Interface.h Раскрывающийся текст
Инструкции по сборке базовой библиотеки Base: gcc,icc: CXXFLAGS: -fPIC LDFLAGS: -nodefaultlibs -shared mingw: для венды установить дефайн__DLL (для экспорта) CXXFLAGS: LDFLAGS: -enable-auto-import [-enable-runtime-pseudo-reloc] -Wl,--kill-at Заголовок базового класса Base.h Раскрывающийся текст
Base.cpp не привожу, он тут не важен. Там можно что-то выполнять, какие-то базовые действия. Инструкции по сборке библиотеки Derived: gcc,icc: CXXFLAGS: -fPIC [-enable-runtime-pseudo-reloc] LDFLAGS: -nodefaultlibs -shared -lBase mingw: для венды установить дефайн __DLL (для экспорта) CXXFLAGS: LDFLAGS: -enable-auto-import [-Wl,--allow-multiple-definition] Заголовок файла основной динамически загружаемой библиотеки Derived.h Раскрывающийся текст
Пример реализации основной динамически загружаемой библиотеки Derived.cpp Раскрывающийся текст
Инструкции по сборке вызывающей программы: gcc,icc: CXXFLAGS: -fPIC LDFLAGS: mingw: CXXFLAGS: LDFLAGS: -enable-auto-import [-enable-runtime-pseudo-reloc] [-Wl,--allow-multiple-definition] -Wl,--kill-at Пример загрузки/выгрузки библиотеки Derived и использования класса (вызов метода init): Раскрывающийся текст
Примечание: при вызове _pInterface->init() будет вызван метод init класса Derived. Сообщение отредактировал Iron Bug - 12.3.2011, 18:08 |
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 24.6.2025, 7:11 |