What is FastSharemem?
Most Delphi developers are resigned to the fact that to use dynamically-allocated memory (objects, strings etc) across DLLs, Sharemem.pas must be included, Borlndmm.dll must be bundled with their application, and its performance costs paid.
In fact, this is one of Delphi's weaknesses. When using DLL's and Sharemem, all memory allocations are slowed down, including simple string operations and object creation.
FastSharemem attempts to provide an alternative. It is a fast, lightweight replacement for Sharemem.pas and Borlndmm.dll which requires no runtime DLL, and incurs virtually no performance penalty. It can be downloaded here. For a discussion of why you might require Sharemem or a replacement, see the page on memory management.
FastSharemem has also been reported to fix unsolved "Invalid Pointer Operation" or Runtime Errors with Sharemem/Borlndmm.dll. If you're using Sharemem properly and still getting these errors, then you might want to try FastSharemem.
Thanks go out to the
following: Darryl Strickland, Ai Ming, Nagy Krisztián, Maurice Fletcher
and Alex Blach. FastSharemem is getting to be quite mature, thanks to their
FastSharemem is distributed with full source code, and is available absolutely free of charge. To get it, see the download section below.
Starting with version 2.00, FastSharemem works through a completely different mechanism. It now uses a placeholder window class to pass data between modules. Through this, a common Delphi heap is shared between EXE's and DLL's. This is done to simplify the code; it is now much shorter and simpler. It is also considerably safer, with no virtual memory-management tricks involved. Another benefit is that it works with all 32-bit Delphi versions (versions 2.0 and above), although it has only been tested on versions 3 and above. It has been tested on Windows 95, 98, ME, 2000, XP and 2003.
The FastSharemem code comes into play only when each Delphi DLL or EXE is loaded into memory. After that, FastSharemem is no longer involved. Each memory allocation, in both EXE and DLL's, now work just as they do when there are no DLLs--unlike Sharemem/Borlndmm.dll, there is no "memory middleman". Your application functions exactly as it does when only a single .EXE is involved. This improves performance, and eliminates many bugs.
FastSharemem is very simple and very small; the entire functional code is less than 70 lines!
Version 2.10 adds the GetAllocMemCount and GetAllocMemSize functions, which, as in Sharemem, replace the AllocMemCount and AllocMemSize global variables. These calls are redirected to the common heap, wherever it happens to be. Without FastSharemem, AllocMemCount and AllocMemSize return information about memory only in the Delphi application's heap, which means that in a DLL application, it returns only the blocks allocated within that DLL, not the entire application. GetAllocMemCount and GetAllocMemSize, on the other hand, return information for the entire application, for all EXEs and all DLLs (provided they use FastSharemem of course).
Details (old, pre-version 2.00)
This information is obsolete starting with FastSharemem version 2.00.
Version 1.21 and up now attempts to search for the signature bytes starting from the top of process memory, subject to a maximum of 16 64k pages (Thanks to Ai Ming for this).
For comparison, Borland's Sharemem.dll works by installing a custom memory manager. The design of the Delphi runtime allows the default memory manager to be replaced with a custom one, much as you might override the new operator in C++. It then diverts all heap calls to the Borldnmm.dll, which is (probably) a Delphi application that simply serves as a common heap; it merely exposes its own heap.
In contrast, FastSharemem works by creating a small process-global memory from which all modules (EXE, DLLs) can look up the address of a common heap. This common heap is the heap of the first module to "register" itself, and is typically the first implicitly loaded DLL. When all DLLs are dynamically loaded, the common heap will belong to the EXE. All heap calls are directed to the common heap.
The common heap address is stored in a record at an absolute position in memory. This is position is computed as the beginning of the last full 64k block:
Position = ((LastValidAddress div 64k)-1) * 64k
The record also contains signature bytes for verification, and these are further combined with the process ID, for additional safety. Since win32 DLLs share a single address space per process, only the application's DLLs get to see the record and "install" the shared heap. For more details, please see the code.
Using FastSharemem pre 2.00 with Delphi 3
If you're using Delphi 3 then use this file. If you need to integrate a Delphi 3 EXE/DLL with another app written in higher versions, you can use this version too; just remember to use this unit with all of the applications, including those being built with higher versions.
Again, the above information is obsolete starting with FastSharemem version 2.00.
Simply include FastSharemem.pas as the first unit in your .DPR file (for the EXE and DLLs), just as you would use Sharemem.
Usage with Leak Detectors
If you need to use FastSharemem with MemCheck or other leak detectors, remember to include the FastSharemem unit first, followed by the leak detector unit. This needs to be done for all modules (EXE and DLL). For MemCheck, for example, put FastSharemem as the first unit in the uses clause, followed by MemCheck. Do the same for all other EXE/DLL projects. For MemChk, also follow the guidelines for setting your project options.
A zip file containing the current FastSharemem.pas unit is available here. This version now works with all 32-bit Delphi versions (version 2 and above).
(c) 2002 emil santos