|
|
 |
 |
|
|
 |
 |
|
Join the Discussion
|
"Post your views, comments, questions and doubts to this article."
Discuss!
|
|
 |
 |
|
|
 |
 |
 |
Article submitted by Emil Santos
Delphi memory manager problems in dynamic libraries. An info on Delphi memory allocation and dynamic-link libraries (DLL). Why and when an 'Invalid pointer operation' exception strikes and how to fight against it. How to properly use strings as parameters in DLL functions.
DLL - dynamic link library
A Dynamic Link library, or DLL, is a collection of routines that can be called by applications and by other DLLs. Like units, DLLs contain sharable code or resources, they provide the ability for multiple applications to share a single copy of a routine they have in common. The concept of DLLs is the core of the Windows architectural design, and for the most part Windows is simply a collection of DLLs. For more info check the article: "Dynamic Link Libraries and Delphi"
"Important note about DLL memory management"
Borland's comments within a wizard-generated DLL project:
{ Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. }
Why are these precautions necessary? The reason is rooted in the way Delphi allocates memory. While Windows provides native memory allocation routines (VirtualAlloc, HeapAlloc, GlobalAlloc, LocalAlloc etc.), Delphi implements its own allocation policy, or more accurately a suballocator. In Pascal parlance, it is called a heap (not to be confused with priority heaps); C/C++ programmers would be more familiar with the term free store.
The task of the suballocator is to allocate all dynamic memory: from raw memory explicitly allocated by the programmer to that implicitly allocated by the compiler, as when creating strings, dynamic arrays and objects.
Few developers realize that they are implicitly allocating memory in statements such as:
var s: string
...
s := s + 'abc';
|
The dynamic-allocation functions most Delphi users are familiar with are GetMem(), FreeMem(), and New() and Dispose(). But actually many seemingly simple actions in Delphi can result in heap memory being allocated or deallocated. Among them:
- Object creation using a constructor
- Long string variables, and operations on them
- Operations on short string variables
- Creation and resizing of dynamic arrays
- String/array values in variants
- Explicit allocation using GetMem()/FreeMem(), New() and Dispose()
In Delphi, all objects "live" on the heap. This is similar to Java, and C# (belying Java/Delphi influences), but not to C++, where objects may live on the stack, heap and even in the data segment. Developers familiar with 16-bit windows programming may be wondering why Delphi doesn't use Windows heaps (via HeapCreate()/HeapAlloc()/HeapFree() etc) or even the virtual memory functions VirtualAlloc()/VirtualFree(). The simple reason is speed. The Windows heap functions are very slow compared to Delphi's native allocation. The virtual memory allocations are even slower, but this is only because they were not designed for allocating large numbers of small blocks (since that is what heaps are for). However the suballocator ultimately calls these virtual memory functions when it needs large blocks from which to suballocate.
The memory manager code resides in System.pas and GetMem.inc, and as such, is compiled with every application. This is not normally a problem, but in applications using DLLs also written in Delphi, this has certain implications: since a DLL is a separately compiled application, it receives its own copy of the memory manager, and thus a separate heap. This is the most important thing to remember: each distinct application, whether an .exe or .dll, manages its own heap. All subsequent problems arise simply from having one exe/dll mistakenly manage a piece of memory that does not live in its own heap.
On the next page, find out about heaps, and why the sentance "...pass string information using PChar or ShortString parameters." can be misleading...
Next page > The solution > Page 1, 2
|