Использование диспетчера памяти приложения delphi в DLL-библиотеке delphi (без перекомпиляции приложения) - PullRequest
0 голосов
/ 30 августа 2009

Мне нужно написать DLL (с ​​использованием Delphi), которая динамически загружается в приложения Delphi и выполняет запросы RTTI (типичная операция - получение строковых значений для свойств элемента управления). Классическая проблема заключается в том, что передача строк (и объектов) между приложением и DLL является проблематичной из-за различных менеджеров памяти, используемых в обоих (это может привести к проблемам с памятью, например, диспетчер памяти DLL попытается освободить память, выделенную диспетчером памяти приложения).

Есть ли способ установить диспетчер памяти DLL в диспетчер памяти приложения таким образом, чтобы он не зависел от версии Delphi? Есть мысли?

Октябрь 2010 г. редактировать:

Поскольку интерес к этой теме почти утрачен - я опишу (довольно плохое) решение, которое я выбрал, чтобы другие поняли, почему я не принял ни один из предложенных ответов.

Таким образом, хакерский способ выполнить что-то вроде этого - найти RVA структуры MemoryManager (см. Часть реализации System.pas) и жесткий код в DLL. Таким образом, DLL сможет установить свой личный менеджер памяти таким же, как у приложения, в которое он загружается. Это работает с некоторыми ограничениями и проблемами; в любом случае - это зависит от параметров компилятора и компоновщика Delphi.

Хотя это не тот ответ, который я искал, - я не ожидаю ничего лучшего, чем это.

Ответы [ 4 ]

7 голосов
/ 30 августа 2009

Используйте один и тот же менеджер памяти для вашего приложения и ваших DLL.

Для последней версии Delphi, включающей новый диспетчер памяти FastMM, используйте SimpleShareMem в качестве 1-го модуля как в приложении, так и в проектах DLL.

Или загрузите полный FastMM4 из SourceForge , установите флаги в FastMM4Options.Inc (ShareMM, ShareMMIfLibrary, AttemptToUseSharedMM) и поместите FastMM4 в качестве 1-го блока в приложении и проектах DLL.

1 голос
/ 31 августа 2009

Другим подходом будет использование COM. Это не относится к конкретной версии Delphi, но потребует от вас создания и реализации com-интерфейса в вашем основном приложении, которое предоставляет необходимые сервисы для вашей DLL. После загрузки DLL вы должны передать ссылку на интерфейс в DLL и использовать ее вместо этого. Другое преимущество этого подхода состоит в том, что любой язык, который может создавать файлы DLL и использовать com-интерфейсы, мог бы выступать в качестве плагина. Конечно, Delphi будет предпочтительным инструментом, главным образом потому, что он делает оба требования безболезненными.

Я не уверен, что RTTI называет ваши разработки из вашей DLL, но лучшее место для них находится внутри вашего приложения, чтобы избежать любых проблем с переводом, которые могут возникнуть между версиями Delphi, когда существует несоответствие компилятора между dll и исполняемым файлом.

0 голосов
/ 24 февраля 2011

Хорошо, так как альтернативы нет - ответом будет хакерское решение .

  1. найти RVA структуры MemoryManager (см. Часть реализации System.pas)
  2. Используйте его в вашей DLL, чтобы настроить собственный менеджер памяти таким же, как у приложения, в которое он загружается.

Как уже указывалось в основной части моего вопроса - он работает с некоторыми ограничениями и очень хрупок по объему параметров компилятора и компоновщика

0 голосов
/ 30 августа 2009

Вот хорошая статья, в которой есть несколько рекомендаций:

http://www.codexterity.com/memmgr.htm

Я также нашел это:

http://sourceforge.net/projects/fastmm/

Я не пробовал ни одну из рекомендованных ими библиотек. Это может дать вам независимость от версии, а может и нет. Если вы хотите распространять DLL и поддерживать разные версии Delphi, это может быть проблематично. Один из вариантов - скомпилировать версию для нескольких основных выпусков.

Примечание: неясно, когда FastSharemem последний раз обновлялся; может быть устаревшим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...