繁体   English   中英

在delphi DLL中使用delphi应用程序的内存管理器(无需重新编译应用程序)

[英]Using delphi application's memory manager in a delphi DLL (without recompiling the application)

我需要编写一个DLL(使用Delphi),该DLL将被动态加载到delphi应用程序中并进行RTTI查询(典型的操作是获取控件属性的字符串值)。 典型的问题是,由于在两者之间使用不同的内存管理器,因此在应用程序和DLL之间传递字符串(和对象)存在问题(这可能会导致内存问题,例如DLL的内存管理器将尝试释放由应用程序的内存管理器分配的内存)。

有没有一种方法可以将DLL的内存管理器设置为应用程序的内存管理器,而不依赖于delphi版本? 有什么想法吗?

2010年10月编辑:

由于对该主题的兴趣几乎消失了-我将描述最终导致的(相当差的)解决方案,以便其他人理解为什么我不接受任何建议的答案。

因此,执行此类操作的一种简便方法是在MemoryManager结构中找到RVA (请参阅MemoryManager实现部分)并在DLL中进行硬编码。 这样,DLL可以将其专用内存管理器设置为与正在加载的应用程序相同。 它具有一些局限性和问题; 无论如何-这是非常依赖Delphi编译器和链接器选项的。

尽管这不是我一直在寻找的答案-我期望没有比这更好的了。

为您的应用程序和DLL使用相同的内存管理器。

对于包含新的FastMM内存管理器的Delphi的最新版本,在应用程序和DLL项目中都将SimpleShareMem用作第一单元。

从SourceForge下载完整的FastMM4 ,在FastMM4Options.Inc(ShareMM,ShareMMIfLibrary,AttemptToUseSharedMM)中设置标志,并将FastMM4作为应用程序和DLL项目中的第一单元。

另一种方法是使用COM。 它不是特定于Delphi的版本,而是需要您在主应用程序中创建并实现com接口,该接口为DLL提供了必要的服务。 加载DLL之后,您可以将接口引用传递给DLL并使用它。 这种方法的另一个优点是,任何可以创建DLL文件并使用com接口的语言都可以充当插件。 当然,Delphi将是首选的工具,主要是因为它使这两个要求都变得轻松。

我不确定RTTI调用您的DLL是什么,但是对于那些DLL来说,最好的选择是在您的应用程序内部,以避免当dll和可执行文件之间的编译器不匹配时,在Delphi版本之间可能发生的翻译问题。

这是一篇不错的文章,其中包含一些建议:

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

我也发现了这一点:

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

我没有尝试过他们推荐的任何一个库。 它可能使您具有版本独立性,但可能没有。 如果要分发DLL并支持不同的Delphi版本,则可能会出现问题。 一种选择是为多个主要版本编译一个版本。

注意:尚不清楚上一次更新FastSharemem的时间。 它可能已过时。

好的,因为没有其他选择-我自己的hacky解决方案将是答案:

  1. 找到的MemoryManager结构的RVA(指的实现部分System.pas
  2. 在DLL中使用它可以将其自己的内存管理器设置为与要加载到的应用程序相同。

正如我的问题中已经提到的那样-它有一些限制,并且在编译器和链接器选项的范围内非常脆弱

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM