У меня есть общий объект C, с которым я загружаюсь dlopen
, Общий объект C включает другую библиотеку в качестве статического архива (полный путь указан /usr/local/.../libsomelib.a
). libsomelib.a
является библиотекой C ++ и имеет глобальные и статические локальные переменные.
В Ubuntu статические инициализаторы не запускаются при открытии общей библиотеки с RTLD_GLOBAL
а также RTLD_GLOBAL | RTLD_LAZY
, Симптом, который я вижу, — это сбой программы.
Поведение, которое я вижу, похоже на связь с -nostartfiles
или же -nostdlib
(но я ими не пользуюсь). Я нашел похожую тему в Статические конструкторы C ++ и общие библиотеки dlopen’d, но это для системы NetBSD.
Если EXE явно включает libsomelib.a
и вызывает функцию из нее, библиотека C ++ инициализируется, и программа больше не падает при вызове через указатель функции.
РЕДАКТИРОВАТЬ: вот как создается общий объект (это самый простой случай, который я видел, без смешения / сопоставления C и C ++). cryptopp-so-test.exe
звонки dlopen
:
CXXFLAGS = -g -ggdb -fPIC -DDEBUG -O1 -Wall -Wextra -Wno-unused -DUSE_PRECOMPILED_HEADERS=1 -I. -I/usr/local/include/cryptopp
...
precompile:
$(CXX) $(CXXFLAGS) pch.h -o pch.h.gch
cryptopp-so-test.exe: precompile $(EXEOBJECTS)
$(CXX) $(CXXFLAGS) -o $@ $(EXESOURCES) -ldl -lpthread
dsotest: precompile $(DLLOBJECTS)
$(CXX) $(CXXFLAGS) $(DLLSOURCES) -o dsotest-1.so -shared /usr/local/lib/libcryptopp.a
Хотя приведенный выше код создает один EXE (cryptopp-so-test.exe) и один SO (dsotest-1.so), я фактически собираю и загружаю 4 общих объекта (они создаются одинаково).
Какие флаги (или другие методы) следует использовать, чтобы обеспечить запуск статических инициализаторов, когда общий объект C с компонентами C ++ dlopen
«D?
В Ubuntu статические инициализаторы не запускаются при открытии общей библиотеки с RTLD_GLOBAL и RTLD_GLOBAL | RTLD_LAZY.
Когда ты dlopen
общая библиотека, глобальные конструкторы являются называется. Вы, вероятно, делаете неверные выводы.
Симптом, который я вижу, — это сбой программы.
Этот симптом может быть вызван что-нибудь. Вам нужно посмотреть на сбой в отладчике и понять, что его вызывает, а не слепо угадывать «статические инициализаторы».
Одно из различий между ссылками libsomelib.a
в основной исполняемый файл и связывание его с общей библиотекой заключается в том, что в зависимости от того, какой код вызывает какие функции, вы можете получить совершенно разные части libsomelib.a
включены в каждый (компоновщик будет тянуть только в части libsomelib.a
то, что он может видеть, необходимо).
Вы можете попробовать связать все libsomelib.a
в общую библиотеку следующим образом:
g++ $(OBJS) -o dsotest-1.so -shared \
-Wl,--whole-archive -lsomelib -Wl,--no-whole-archive
Других решений пока нет …