Передача данных 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++.

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
920
5

Ответы 5

Вы могли либо:

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

Второй вариант встречается очень редко, но можно создать библиотеку импорта только из файла 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. Эта экспортированная функция может передавать данные как обычную структуру в стеке.

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

Другие вопросы по теме