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

时间:2009-08-29 22:09:22

标签: delphi dll memory-management memory-leaks

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

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

2010年10月编辑:

由于对这个主题的兴趣几乎丢失了 - 我将描述我最终得到的(非常差的)解决方案,以便其他人理解为什么我不接受任何建议的答案。

所以 hacky 执行此类操作的方法是查找RVA MemoryManager结构(参见System.pas的实现部分)和DLL中的硬编码。这样,DLL就能够将其私有内存管理器设置为与其加载的应用程序相同。它适用于一些限制和问题;无论如何 - 它是非常Delphi编译器&链接器选项依赖。

虽然这不是我正在寻找的答案 - 但我没想到会有更好的结果。

4 个答案:

答案 0 :(得分:7)

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

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

或者下载full FastMM4 from SourceForge,在FastMM4Options.Inc(ShareMM,ShareMMIfLibrary,AttemptToUseSharedMM)中设置Flags,并将FastMM4作为应用程序和DLL项目中的第一个单元。

答案 1 :(得分:1)

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

我不确定你的DLL会调用你的RTTI,但是那些最好的地方是你的应用程序,以避免在dll和可执行文件之间存在编译器不匹配时Delphi版本之间可能发生的翻译问题。 / p>

答案 2 :(得分:0)

这是一篇很好的文章,有一些建议:

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

我也发现了这个:

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

我没有尝试过他们推荐的任何一个库。它可能会让你获得版本独立性,但它可能不会。如果您想分发DLL并支持不同的Delphi版本,那可能会有问题。一种选择是为几个主要版本编译一个版本。

注意:目前还不清楚FastSharemem上次更新的时间;它可能已经过时了。

答案 3 :(得分:0)

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

  1. 找到MemoryManager结构的RVA(参考System.pas的实现部分)
  2. 在DLL中使用它将其自己的内存管理器设置为与其加载的应用程序相同。
  3. 正如我在问题正文中已经说过的那样 - 它有一些限制,并且在编译器的范围内非常脆弱。链接器选项