views:

477

answers:

3

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, e.g. 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.

A: 

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.

TrueWill
+6  A: 

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.

François
sorry, but you've answered some other question, not mine ;)
Andrey
Sharing the memory allocator between an EXE and DLL is the problem ShareMem (and, by extension, FastMM's SimpleShareMem) was created to solve. How does this not answer the question?
Joe White
because the question is how to hack into another application's memory manager (whatever it is) and not recompile it with a different one. Sorry, if it it wasn't clear but the question is about cases when recompiling the application is not an option, we only have control over the DLL that will be loaded into it at runtime.
Andrey
+1  A: 

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.

skamradt