unit COMMM; (* system purpose: Simple COM based memory manager replacement, tested for Delphi 4-7 author: © 2004, Thaddy de Koning, mailto:thaddy[@]thaddy.com status: Use as you like, freeware, but I retain the copyrights. No warranties *what*so*ever*. Only Dutch is law applicable. (Since it understands the "WhatSoEver" part a little better than most) Remarks: Use this if you write COM based applications and/or don't want to use ShareMem.pas with BORLNDMM.DLL. Also suitable for KOL and KOL dll's. ***************************************************************** This is very simple code, but with far reaching implications. ***************************************************************** Please read these comments carefully before you use this unit and make shure you fully understand what it does. ***************************************************************** Features: + All memory is marshalled through COM. This means a.o. that COM provides the reference counting across modules, so you don't need the ShareMem unit and don't need to distribute BORLNDMM.DLL when using long strings, dynamic arrays etc in your dll code. COM marshalling simply overrides and ignores Delphi's reference counting mechanism. During extensive tests I encountered no problems. - Because of this it may have an effect on highly specialized code that hacks - and I mean hacks - into the Delphi reference count mechanism itself, but that is very rare and you will know it when you do so. Most programmers need not worry about this. + It highly simplifies writing COM based applications since you can use Delphi memory access functions without having to worry how to allocate the memory. Simply put: getmem and coTaskMemAlloc are basically the same and New and (Re)Allocmem provide COM memory as well. Even strings and dynamic arrays etc are COM based memory, since they rely on these low level routines. + This unit guarantees that almost all means of allocating memory with Delphi can be used transparantly with COM with the exception of the VirtualAlloc - page - related low level WIN32 API. + Since it is all COM marshalled memory it is fully shareable between COM based applications written in other languages like VB or C++ and with some thought even with the scripting host. + Your existing code is suddenly COM memory compliant! Just recompile. + Your existing dll code maybe managed code (.net) compliant since the .NET garbage collection feature seems to rely on COM memory - management on the lowest level. Some tests done, but not extensive. + It has some basic garbage collection capabilities, even under WIN 95/98, since COM releases the orphaned memory if it knows for shure that the owning processes are unloaded. This does NOT mean your application cannot leak while running! -/+ It is a little slower than Delphi's default memorymanager, though, but the granularity - 16 bytes - is pretty good. -/! Read the warning below! Its use has ambiguities you may overlook. Use: Simply include it as the *first* unit in the uses clause of your project file (.dpr). **************************************************************************** Warning: Do not forget to document that you used it! It is very easy to make a mistake later and it will probably break your code if you forget about it! Most other memory manager replacements do not have this ambiguous disadvantage, so be warned and be very very carefull! I highly recommend marking every single unit that may depend on it. Trust me, it is very comfortable to use but very easy to forget. This may be easily overlooked, even if you use a versioning system. ******************************************************************* *) interface {.$DEFINE I_HAVE_READ_THE_WARNING} {$IFNDEF I_HAVE_READ_THE_WARNING} PLEASE READ THE WARNING! {$ENDIF} implementation uses //Both units do not allocate memory, so are safe to use Windows,ActiveX; function ComGetMem(size: Integer): Pointer; begin Result := coTaskMemAlloc(size); {$IFOPT D+} FillChar(Result^,Size,$CC); // = int3, so you get a debug breakpoint if you // have troubles {$ENDIF} end; function ComFreeMem(p: Pointer): Integer; begin coTaskMemFree(P); Result:= 0;//!!!Magic!!! end; function ComReallocMem(p: Pointer; size: Integer): Pointer; begin Result:=CoTaskMemRealloc(p,Size); end; const ComMemoryManager: TMemoryManager = ( GetMem: ComGetMem; FreeMem: ComFreeMem; ReallocMem: ComReallocMem); var OldMM: TMemoryManager; initialization GetMemoryManager( OldMM ); SetMemoryManager( ComMemoryManager ); finalization SetMemoryManager( OldMM ); end. // Was that all? yes it was!