Поддержка нескольких экземпляров подключаемой библиотеки DLL с глобальными данными

Контекст: я преобразовал устаревший автономный движок в подключаемый компонент для инструмента композиции. Технически это означает, что я скомпилировал базу кода движка в C DLL, которую я вызываю из оболочки .NET с помощью P / Invoke; оболочка реализует интерфейс, определенный инструментом композиции. Это работает довольно хорошо, но теперь я получаю запрос на загрузку нескольких экземпляров движка для разных проектов. Поскольку движок хранит данные проекта в наборе глобальных переменных, и поскольку DLL с базой кода движка загружается только один раз, загрузка нескольких проектов означает, что данные проекта перезаписываются.

Я вижу ряд решений, но все они имеют некоторые недостатки:

  1. Вы можете создать несколько DLL с одним и тем же кодом, которые Windows воспринимает как разные DLL, поэтому их код не используется совместно. Вероятно, это уже работает, если у вас есть несколько копий DLL движка с разными именами. Однако движок вызывается из оболочки с использованием атрибутов DllImport , и я думаю, что при компиляции оболочки необходимо знать имя библиотеки DLL движка. Очевидно, если мне нужно скомпилировать разные версии оболочки для каждого проекта, это будет довольно громоздко.

  2. Движок может работать как отдельный процесс. Это означает, что оболочка запускает отдельный процесс для движка при загрузке проекта и использует некоторую форму IPC для связи с этим процессом. Хотя это относительно чистое решение, оно требует некоторых усилий, чтобы заставить его работать. Я не знаю, какая технология IPC лучше всего подходит для создания такой конструкции. Также могут быть значительные накладные расходы на обмен данными: механизму необходимо часто обмениваться массивами чисел с плавающей запятой.

  3. Механизм может быть адаптирован для поддержки нескольких проектов. Это означает, что глобальные переменные следует поместить в структуру проекта, и каждая ссылка на глобальные объекты должна быть преобразована в соответствующую ссылку, относящуюся к конкретному проекту. Существует около 20-30 глобальных переменных, но, как вы можете себе представить, на эти глобальные переменные ссылаются из всей базы кода, поэтому это преобразование нужно будет выполнять некоторым автоматическим способом. Связанная с этим проблема заключается в том, что вы должны иметь возможность ссылаться на «текущую» структуру проекта во всех местах, но передача этого в качестве дополнительного аргумента в каждой сигнатуре функции также является громоздкой. Существует ли метод (на языке C) для рассмотрения текущего стека вызовов и поиска в нем ближайшего включающего экземпляра соответствующего значения данных?

Может ли сообщество stackoverflow дать совет по этим (или другим) решениям?

6
задан Bruno De Fraine 10 January 2011 в 10:03
поделиться