Передача данных EXE в одну или несколько библиотек DLL

Наше текущее приложение представляет собой один EXE-файл OpenGL, содержащий несколько страниц. EXE отвечает за доступ к данным, отправляемым по сети через UDP. Он накапливает данные и сохраняет их во множестве одноэлементных структур. Отдельные страницы в EXE-файле получают доступ к одноэлементным структурам для обработки данных по своему усмотрению.

В попытке уменьшить размер нашего EXE-файла и поддержать наши попытки управления конфигурацией мы решили разделить страницы на одну DLL, которую будет загружать EXE. Мы намерены сделать EXE оболочкой, в которую будут загружены страницы из DLL. EXE по-прежнему будет нести все обязанности по обмену данными (UDP, Corba, User и т. д.). Страницы по-прежнему будут нести ответственность за отображение всего, что они делают.

Вопрос (наконец) звучит так: как мне передать это множество данных, собранных из EXE, на потребляющие страницы на основе DLL. Концепция синглтона больше не выдерживает критики, поскольку используемые нами синглтоны (ACE_Singleton) не допускают такого уровня направления. Мы можем экспортировать синглтоны из DLL в потребляющий EXE-файл в течение всего дня, но мне еще предстоит выяснить обратное. Я придумал следующие варианты - ни один из них мне не нравится, поэтому я надеялся, что у кого-то есть лучший :)

  1. Оберните все данные, которые в настоящее время хранятся в отдельных синглтонах, в другую DLL, которая будет экспортировать «настоящий» синглтон. Например. Синглтон, экспортируемый из DLL, будет одним и тем же - независимо от того, какой EXE-файл его загрузит - вроде общей памяти. Это интригующий выбор, но он может вызвать проблемы в наших сценариях развертывания. Я мог бы подробно рассказать об этих проблемах, если люди действительно поражены этой идеей.
  2. Создайте статическую структуру уровня DLL, содержащую все соответствующие данные. EXE передаст эти данные в DLL при загрузке DLL, чтобы страницы, содержащиеся в DLL, имели доступ к данным. Это кажется самым простым решением, даже если оно влечет за собой редактирование каждой отдельной страницы в нашем приложении — более 100. Это также кажется немного неаккуратным. Все данные находятся только в глобале. Не очень сексуальный или C++y.

Итак, у кого-нибудь еще есть решение этой проблемы?

Приложение написано с использованием Visual C++ 9.0 (VisualStudio 2008) для использования в Windows XP. По какой-то причине Vista пока не поддерживается в нашей лаборатории, хотя наши клиенты используют ее.


person Community    schedule 17.09.2008    source источник


Ответы (5)


Дайте всем DLL функцию SetGlobalDataPointer(Singleton*). Ваш EXE вызывает эту функцию перед вызовом любой другой функции DLL. В коде DLL замените все вхождения файла Singleton. by theSingletonPtr->

person MSalters    schedule 01.10.2008

Вы можете:

  • поместите все, кроме самой внешней оболочки, в «общую» DLL;
  • используйте файл DEF для создания функций экспорта из вашего EXE.

Второй встречается очень редко, но можно создать библиотеку импорта только из файла DEF. Используйте LIB /DEF для создания библиотеки импорта. См. раздел Работа с библиотеками импорта и экспортом файлов.

person Mike Dimmick    schedule 17.09.2008

К сожалению, похоже, что у вас есть много существующего кода, с которым нужно повозиться. В этом случае я бы просто выбрал (2), предполагая, что он не станет слишком большим и громоздким.

Судя по вашему описанию, данные на уровне EXE нужно отправлять только один раз при загрузке DLL.

Если (2) слишком запутанный, я бы немного реорганизовал его, чтобы иметь базовый класс «DLLPage» с функциями Serialize/UnSerialize(). Никогда не экспортируйте сам класс, только отдельные функции, которые вам нужны в нем (это очень помогает при изменении класса... очень странные разрывы случаются при экспорте на уровне класса). Вам понадобятся конструктор/деструкторы и, возможно, каждый публичный член.

Могут возникнуть некоторые проблемы с управлением кучей, поэтому мне также нравится перегружать операции создания/удаления, чтобы все классы использовали централизованную операцию создания/удаления, расположенную во вспомогательной библиотеке DLL.

person darron    schedule 17.09.2008

Прежде чем приступить к разбиению EXE-файла, вы должны прочитать об управлении памятью и библиотеках DLL.

Вот одна статья, в которой говорится о проблемах с объектами CRT, но то же самое относится и к вашим собственным объектам C++.

Потенциальные ошибки при передаче объектов CRT через границы DLL

person Torlack    schedule 17.09.2008

Первый вариант: поместить все данные, которые хранит exe, в разделяемую память. Затем библиотеки DLL могут получить к нему доступ, если у вас есть надлежащая блокировка.

Второй вариант: передать память в dll с помощью экспортированного указателя на функцию - в exe есть функция, dll вызывает в exe другую функцию, которая возвращает эту функцию в виде указателя, который dll может потом вызвать. Эта экспортированная функция может передавать данные как обычную структуру в стеке.

Третий вариант: если вы используете ту же среду выполнения, просто экспортируйте указатель, который дает вам прямой доступ к памяти.

person gbjbaanb    schedule 13.01.2009