Neidhard von Reuental hat folgendes geschrieben: |
hab mir schon mal überlegt den zeiger in ein longword umzuwandeln und in der anwendung zurück in einen zeiger. geht das überhaupt?  |
Natürlich kannst du einen Zeiger in ein LongWord typecasten (zumindest auf 32-Bit Systemen). Aber bringen wird dir das auch nichts. Ob du die Adresse nun von der einen oder der anderen Seite betrachtest, ändert nichts an der Tatsache, dass es eine Adresse ist, die du vom Speichermanager bekommen hast. Und wenn du zwei Speichermanager am laufen hast (EXE und DLL), dann geht das beim Freigeben des Speichers trotzdem nach hinten los.
Es gibt aber mehrere Möglichkeiten, wie du das Problem umgehen kannst.
- Du bindest deine DLL zur Ladezeit (procedure xxx; external dllname;) und importierst den Speichermanager der DLL in die EXE (habe ich noch nie ausprobiert).
- Du alloziierst eine feste Adresse im Speicher, in der du den Record für die Speichermanagerfunktionen der EXE-Datei hinschreibst, und von der du beim Laden der DLL diese ausliest und den Speichermanager der DLL durch diese Funktionen ersetzt.
- Du setzt bei beiden (EXE und DLL) den Speichermanager auf den Speichermanager von C/C++ (malloc,free,realloc).
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| unit CMemMan;
interface
procedure free(p: Pointer); cdecl; function malloc(Size: Integer): Pointer; cdecl; function realloc(p: Pointer; Size: Integer): Pointer; cdecl;
implementation
const msvcrt = 'msvcrt.dll';
procedure free(p: Pointer); cdecl; external msvcrt; function malloc(Size: Integer): Pointer; cdecl; external msvcrt; function realloc(p: Pointer; Size: Integer): Pointer; cdecl; external msvcrt;
function CGetMem(Size: Integer): Pointer; begin Result := malloc(Size); end;
function CFreeMem(p: Pointer): Integer; begin free(p); Result := 0; end;
function CReallocMem(p: Pointer; Size: Integer): Pointer; begin Result := realloc(p, Size); end;
const CMemoryManager: TMemoryManager = ( GetMem: CGetMem; FreeMem: CFreeMem; ReallocMem: CReallocMem; );
initialization SetMemoryManager(CMemoryManager);
finalization
end. |
Diese Unit musst du nur als aller erste Unit in der DLL und der EXE Datei einbinden (in der .dpr-Datei). Danach bist du von allen Speichermanager-Problemen bezüglich DLLs befreit.