简体   繁体   中英

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

I need to write a DLL (using Delphi) which is dynamically loaded into delphi applications and makes RTTI queries (typical operation is to obtain string values for control properties). The classic problem is that passing strings (and objects) between application and DLL is problematic due to different memory managers used in both (this might lead to memory issues, eg DLL's memory manager would try to free the memory allocated by Application's memory manager).

Is there a way to set DLL's memory manager to application's memory manager in a way that would not depend on delphi version? Any thoughts?

October 2010 edit:

Since interest to this topic is almost lost - I'll describe the (quite poor) solution which I ended up with so that others would understand why I didn't accept any of the proposed answers.

So a hacky way to perform something like this would be to find RVA of MemoryManager structure (refer to implementation part of System.pas) and hardcode in the DLL. This way, DLL would be able to set its private memory manager to be the same as that of the application it is being loaded into. It works with some limitations and issues; anyway - it is very Delphi compiler & linker options dependent.

Though it is not an answer I was searching for - I do not expect anything better than this.

Use the same memory manager for your application and your DLLs.

For recent version of Delphi that includes the new FastMM memory manager, use SimpleShareMem as the 1st unit in both your application and the DLL projects.

Or download the full FastMM4 from SourceForge , set the Flags in FastMM4Options.Inc (ShareMM, ShareMMIfLibrary, AttemptToUseSharedMM) and put FastMM4 as the 1st unit in both the application and the DLLs projects.

Another approach, would be to use COM. It would not be specific to a version of Delphi, but would require you to create and implement a com interface in your main application which provided the necessary services to your DLL. After you loaded your DLL you would then pass the interface reference to the DLL and use it instead. The other advantage of this approach is that any language that can create DLL files and use com interfaces would be able to act as a plugin. Of course Delphi would be the tool of choice, mainly because it makes both requirements painless.

I am not sure what RTTI calls your making from your DLL, but the best place for those are inside your application to avoid any problems in translation that can occur between Delphi versions when there is a compiler mismatch between dll and executable.

Here's a nice article that has some recommendations:

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

I also found this:

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

I haven't tried either of the libraries they recommend. It might get you version independence, it might not. If you're wanting to distribute the DLL and support different Delphi versions, that might be problematic. One option would be to compile a version for several of the major releases.

Note: It's unclear when FastSharemem was last updated; it may be obsolete.

Ok, as there aren't any alternatives - the hacky solution of my own would be the answer:

  1. find RVA of MemoryManager structure (refer to implementation part of System.pas )
  2. Use it in your DLL to set its own memory manager to be the same as that of the application it is being loaded into.

As already stated in the body of my question - it works with some limitations and is very fragile in scope of compiler & linker options

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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