Zitat von
himitsu:
PS2: du hast dir aber auch einen Shared-MemoryManager besorgt?
denn du willst hier ja anscheinend Speicher über die Programmgrenzen hinweg verwalten/bearbeiten
und das geht nur im SELBEN speichermanager ... hier hat aber standardmäßig die EXE und die
DLL jeder ihren eigenen Manager.
Es sei denn du verwendest einen WideString, welcher nicht über den Delphi-MemoryManager läuft, sondern über den vom OLE32-System.
Man kann es auch anders machen - indem man in der
DLL den Speichermanager der Hostanwendung benutzt. Das gleiche benutze ich bei meiner Script-Sprache bei den Packages auch. Im Enddefekt geht das ganz einfach:
in der
DLL erstellt man so eine Funktion:
Delphi-Quellcode:
var
oldMM : TMemoryManager;
newMM : TMemoryManager;
useMM : boolean;
procedure DLL_SetMemoryManager(
const MemoryManager: TMemoryManager);
stdcall;
begin
if not useMM
then
begin
// den bisherigen MemoryManager der DLL speichern
GetMemoryManager(oldMM);
// den neuen MemoryManager aktivieren
newMM := MemoryManager;
SetMemoryManager(newMM);
// speichern, dass man den neuen MemoryManager benutzt
useMM := True;
end;
end;
procedure DLL_ResetMemoryManager;
stdcall;
begin
// falls ein fremder MemoryManager benutzt wurde
if useMM
then
begin
// den alten wieder zurücksetzen.
SetMemoryManager(oldMM);
useMM := False;
end;
end;
exports
DLL_SetMemoryManager,
DLL_ResetMemoryManager;
Beim laden der
DLL führt man dann so früh wie möglich in der Host-Anwendung die
DLL-Funktion
DLL_SetMemoryManager folgendermaßen aus:
Delphi-Quellcode:
var MemoryManager: TMemoryManager;
begin
GetMemoryManager(MemoryManager);
DLL_SetMemoryManager(MemoryManager);
end;
und beim Beenden bzw. beim Entladen der
DLL ruft man einfach wieder die Funktion
DLL_ResetMemoryManager der
DLL auf.
Wichtig ist dabei: man sollte in der
DLL kein Speicher vor dem
DLL_SetMemoryManager anfordern. Zudem sollte jeder Speicher, der nach dem
DLL_SetMemoryManager angefordert wurde, vor dem
DLL_ResetMemoryManager wieder freigegeben werden.
Grüße