Einzelnen Beitrag anzeigen

Benutzerbild von littleDave
littleDave

Registriert seit: 27. Apr 2006
Ort: München
556 Beiträge
 
Delphi 7 Professional
 
#3

Re: Eine Variable "umziehen"

  Alt 14. Okt 2009, 19:20
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
Jabber: littleDave@jabber.org
in case of 1 is 0 do external raise while in public class of object array else repeat until 1 is 0
  Mit Zitat antworten Zitat