Hier habt ihr noch ein kleines "Abfallprodukt" meines
himXML
Es schleift praktisch jeden Speichermanager von einer Delphi-EXE in eine Delphi-
DLL durch.
Dabei ist es egal, ob nun der Standard-SpeicherManager verwendet wird oder ein Anderer.
Und es wird auch keine zusätzliche Datei benötigt, wie es bei
ShareMem der Fall ist.
Systemvorausstzung:
die
DLL (bzw. die himiSM.pas) benötigt mindestens ein Delphi, wo TMemoryManagerEx verfügbar ist
und die EXE sollte vermutlich mindestens mit Delphi 4 erstellt werden.
Diese
Unit muß in die
DLL aufgenommen werden:
> erster Uses-Eintrag in deren .DPR
Delphi-Quellcode:
Unit himiSM_DLLInit;
Interface
Implementation
{$WARN SYMBOL_DEPRECATED OFF}
Uses Windows;
Var Name:
Array[0..29]
of AnsiChar = '
himiShareMem_xxxxxxxxxxxxxxxx'#0;
i, i2: Integer;
Map: THandle;
View: PAnsiChar;
MemMgr: TMemoryManager;
MemMgrEx: TMemoryManagerEx;
OldMemMgr: TMemoryManagerEx;
Initialization
GetMemoryManager(OldMemMgr);
i2 := GetCurrentProcessId;
For i := 15
downto 0
do Begin
If Byte(i2
and $0F) <= 9
Then Name[i + 13] := AnsiChar((i2
and $0F) + Ord('
0'))
Else Name[i + 13] := AnsiChar((i2
and $0F) - 10 + Ord('
A'));
i2 := i2
shr 4;
End;
Map := OpenFileMappingA(FILE_MAP_READ, False, @
Name);
View := MapViewOfFile(Map, FILE_MAP_READ, 0, 0, 0);
If (Map <> 0)
and Assigned(View)
Then
If Assigned(PPointer(View + 3 * SizeOf(Pointer))^)
Then Begin
CopyMemory(@MemMgrEx, View, SizeOf(MemMgrEx));
SetMemoryManager(MemMgrEx);
End Else Begin
CopyMemory(@MemMgr, View, SizeOf(MemMgr));
SetMemoryManager(MemMgr);
End;
UnmapViewOfFile(View);
CloseHandle(Map);
Finalization
SetMemoryManager(OldMemMgr);
End.
Und zum Laden der
DLL wird dann "einfach" nur noch statt LoadLibrary das LoadLibrary
SM verwendet
Delphi-Quellcode:
Function LoadLibrarySM(LibFileName: PChar): HMODULE;
Var Name: Array[0..29] of AnsiChar;
i, i2: Integer;
Map: THandle;
View: PAnsiChar;
MemMgr: {$IF Declared(TMemoryManagerEx)}TMemoryManagerEx{$ELSE}TMemoryManager{$IFEND};
Error: HRESULT;
Begin
Error := ERROR_INVALID_FUNCTION;
Name := 'himiShareMem_xxxxxxxxxxxxxxxx'#0;
i2 := GetCurrentProcessId;
For i := 15 downto 0 do Begin
If Byte(i2 and $0F) <= 9 Then Name[i + 13] := AnsiChar((i2 and $0F) + Ord('0'))
Else Name[i + 13] := AnsiChar((i2 and $0F) - 10 + Ord('A'));
i2 := i2 shr 4;
End;
Map := CreateFileMappingA(INVALID_HANDLE_VALUE, nil, FILE_MAP_READ, 0, 6 * SizeOf(Pointer), @Name);
View := MapViewOfFile(Map, FILE_MAP_READ or FILE_MAP_WRITE, 0, 0, 0);
_DLL := 0;
Try
If (Map <> 0) and Assigned(View) Then Begin
GetMemoryManager(MemMgr);
ZeroMemory(View, 6 * SizeOf(Pointer));
CopyMemory(View, @MemMgr, SizeOf(MemMgr));
Result := LoadLibrary(LibFileName);
Error := GetLastError;
End Else Begin
Result := 0;
Error := ERROR_ACCESS_DENIED;
End;
Finally
UnmapViewOfFile(View);
CloseHandle(Map);
SetLastError(Error);
End;
End;
Info:
Es macht übrigens auch nichts aus, wenn in einem von Beiden (EXE und
DLL) keiner der Codes eingebaut ist ... in diesem Falls wird einfach nur keine Umleitung eingerichtet.
Also wenn die
DLL mit deim "einfachen" LoadLibrary geladen wird oder die
DLL den Code nicht enthält.
Anhang:
himiSM_DLLInit.pas *
» * kommt in die
DLL
himiSM_LoadLibrary.pas *
» * kommt in die EXE (oder eine andere
DLL) und enthällt die LoadLibrarySM