Наше текущее приложение представляет собой один EXE-файл OpenGL, содержащий несколько страниц. EXE отвечает за доступ к данным, передаваемым по сети через UDP. Он накапливает данные и хранит их во множестве одноэлементных структур. Отдельные страницы в EXE обращаются к одноэлементным структурам для обработки данных по своему усмотрению.
В попытке облегчить следы EXE и поддержать наши попытки управления конфигурацией мы решили разделить страницы на одну DLL, которую будет загружать EXE. Мы намерены сделать EXE-файл оболочкой, в которую будут загружаться страницы из DLL. EXE по-прежнему будет выполнять все коммуникационные обязанности (UDP, Corba, User и т. д.). Страницы по-прежнему будут нести ответственность за отображение того, что они делают.
И наконец, возникает вопрос: как передать это несметное количество данных, собранных из EXE, на страницы, использующие DLL. Концепция синглтона больше не выдерживает критики, поскольку используемые синглтоны (ACE_Singleton) не допускают такого уровня направления. Мы можем экспортировать синглтоны из DLL в исполняющий EXE в течение всего дня, но мне еще предстоит придумать обратное. Я придумал следующие варианты - ни один из них мне не нравится, поэтому я надеялся, что у кого-то там будет лучший :)
Итак, у кого-нибудь еще есть решение этой проблемы?
Приложение написано с использованием Visual C++ 9.0 (VisualStudio 2008) для использования в Windows XP. По какой-то причине Vista пока не поддерживается в нашей лаборатории, хотя наши клиенты ее используют.





Вы могли либо:
Второй вариант встречается очень редко, но можно создать библиотеку импорта только из файла DEF. Используйте LIB / DEF для создания библиотеки импорта. См. Работа с библиотеками импорта и файлами экспорта.
К сожалению, похоже, что вам нужно повозиться с большим количеством существующего кода. В этом случае я бы просто выбрал (2), если он не станет слишком большим и громоздким.
Судя по вашему описанию, данные на уровне EXE нужно отправлять только один раз при загрузке DLL.
Если (2) слишком запутанный, я бы немного реорганизовал его, чтобы иметь базовый класс «DLLPage» с функциями Serialize / UnSerialize (). Никогда не экспортируйте сам класс, только отдельные функции, которые вам нужны (это очень помогает при изменении класса ... очень странные перерывы случаются с экспортом на уровне класса). Вам понадобятся конструктор / деструкторы и, возможно, каждый публичный член.
Могут возникнуть некоторые проблемы с управлением кучей, поэтому мне также нравится перегружать new / delete, и все классы используют централизованное new / delete, расположенное во вспомогательной DLL.
Перед тем, как сделать решительный шаг в разрыве EXE, вы должны прочитать об управлении памятью и библиотеках DLL.
Вот одна статья, в которой говорится о проблемах с объектами CRT, но то же самое относится и к вашим собственным объектам C++.
Возможные ошибки при передаче объектов CRT через границы DLL
Дайте всем библиотекам DLL функцию SetGlobalDataPointer (Singleton *). Ваш EXE вызывает эту функцию перед вызовом любой другой функции DLL. В коде DLL замените все вхождения файла Singleleton. Автор: theSingletonPtr->
Первый вариант: поместить все данные, хранящиеся в exe, в общую память. После этого библиотеки DLL могут получить к нему доступ, если у вас есть надлежащая блокировка.
Второй вариант: передать память в библиотеки DLL с помощью экспортированного указателя на функцию - у exe есть функция, DLL вызывает другую функцию в exe, которая возвращает эту функцию в виде указателя, который затем может вызывать DLL. Эта экспортированная функция может передавать данные как обычную структуру в стеке.
Третий вариант: если вы используете ту же среду выполнения, просто экспортируйте указатель, который дает вам прямой доступ к памяти.