Связать dll со статической библиотекой и загрузить ее в приложение, связанное с той же статической библиотекой
Я создаю приложение, которое поддерживает модули в форме DLL, которые загружаются динамически во время выполнения. Код выложен следующим образом:
ядро - статическая библиотека
У него есть механизм для загрузки общих библиотек и вызова функции "create", которая возвращает новый объект Module (использует общий заголовок).
общая библиотекамодуля (связана с базовой статической библиотекой)
Этот модуль использует общий заголовок модуля, а также использует другие классы из базовой библиотеки (следовательно, почему он связан с основной библиотекой). Он построен для включения всех символов из статических библиотек.
исполняемый файлтестового приложения (связанный с базовой статической библиотекой)
Я получаю фанк, и, казалось бы, спорадическое поведение. Они всегда приводят к нарушениям доступа, но кажется, что переменные-члены, которые я очень явно установил (целые числа), будут распечатаны в более поздних функциях как мусор (я убедился, что они не удаляются ранее). Кажется, это происходит только в том случае, если они загружают динамическую библиотеку (даже если я никогда не вызываю функцию create).
Мой главный вопрос заключается в том, существует ли здесь опасность того, что символы в общей библиотеке будут конфликтовать с символами в исполняемом файле (поскольку они пришли из одной и той же статической библиотеки) и вызывать проблемы, даже если они принадлежат одной и той же статической библиотеке?
1 ответ
Я не могу говорить о поведении Linux и OS X, но в Windows следующее происходит именно так. Поскольку вы говорите, что также хотите компилировать в Windows, это актуально.
Проблема, с которой вы столкнулись, заключается в том, что у вас есть несколько версий всего в ядре. Каждый модуль и само приложение имеют свою собственную копию ядра, и их переменные не являются общими. Это включает в себя среду выполнения C, поэтому такие вещи, как new / delete через границы модуля чреваты опасностью.
Чтобы убедиться, что это именно то, что происходит, создайте простой тест: задайте глобальному значению в ядре значение в своем тестовом приложении, затем из своего динамически загруженного кода попробуйте получить доступ к этому глобальному и посмотрите, что вы получите. Держу пари, что вы увидите, что ваш магазин в глобальном масштабе не будет отражен!
Решения:
1) Сделать ядро общей динамической библиотекой. Это может или не может быть вариантом для вас.
2) Работать очень осторожно со знанием вышеизложенного; Все CRT и / или ваше собственное состояние ядра не будут разделены, поэтому вы должны убедиться, что вещи будут распределены / уничтожены на их собственной стороне границ модуля, среди прочего.
Мое собственное приложение разработано почти идентично вашему; т.е. статическая библиотека с общим кодом, необходимым как приложению, так и модулями, а затем динамически загружаемые плагины, загружаемые ядром приложения.
То, что я делаю для всех общих состояний ядра, к которым необходимо обращаться через модули, - это то, что первое, что делает каждый модуль после загрузки, это установление его "указателя ядра" на создание экземпляров библиотек ядра в приложении. Это гарантирует, что все модули работают с одинаковыми данными.