我需要编写一个DLL(使用Delphi),它动态加载到delphi应用程序中并进行RTTI查询(典型的操作是获取控件属性的字符串值)。 经典的问题是在应用程序和DLL之间传递字符串(和对象)是有问题的,因为两者中使用了不同的内存管理器(这可能导致内存问题,例如DLL的内存管理器会尝试释放由Application的内存管理器分配的内存)。
有没有办法以不依赖于delphi版本的方式将DLL的内存管理器设置为应用程序的内存管理器?有什么想法吗?
2010年10月编辑:
由于对这个主题的兴趣几乎丢失了 - 我将描述我最终得到的(非常差的)解决方案,以便其他人理解为什么我不接受任何建议的答案。
所以 hacky 执行此类操作的方法是查找RVA
MemoryManager
结构(参见System.pas的实现部分)和DLL中的硬编码。这样,DLL就能够将其私有内存管理器设置为与其加载的应用程序相同。它适用于一些限制和问题;无论如何 - 它是非常Delphi编译器&链接器选项依赖。
虽然这不是我正在寻找的答案 - 但我没想到会有更好的结果。
答案 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解决方案就是答案:
System.pas
的实现部分)正如我在问题正文中已经说过的那样 - 它有一些限制,并且在编译器的范围内非常脆弱。链接器选项