Hallo, mir ist gerade aufgefallen, dass ein Programmteile der vorher in einer EXE waren und nun in eine
DLL ausgelagert wurde sich leider ganz anders verhält. Hintergrund ist, dass das Hauptprogramm als
DLL ausgeliefert werden soll um bestimmte Funktionen per Export für andere Programme Verfügung zu stellen da ein Export in als Exe nicht funktionierte.
Hier ein Beispiel:
Delphi-Quellcode:
try
with TFileStream.Create('
C:\test.dat', fmOpenRead)
do
Free;
except
on E:
Exception do
Writeln(E.Classname, '
: ', E.
Message, '
LastError=', GetLastError);
end;
In der Exe ist im except GetLastError=2 aber in der
DLL wird GetLastError auf 0 gesetzt sobald raise in TFileStream.Create aufgerufen wird.
Ich habe die Sache schon im Debuger untersucht und auch die Stelle gefunden, wo das passiert.
Raise ruft intern _RaiseExcept (System.pas) auf die dann per CALL RaiseList in die
Unit Sysinit springt.
Delphi-Quellcode:
asm
MOV CL,ModuleIsLib
MOV EAX,TlsIndex
TEST CL,CL
JNE @@isDll
...
RET
...
@@isDll:
PUSH EAX
CALL TlsGetValue
TEST EAX,EAX
JE @@initTls
end;
Da CL = 1 wird nach @@isDll gesprungen und in TlsGetValue GetLastError auf 0 gesetzt.
Ich habe die Quellen von Delphi2007 und von XE7 verglichen. Es ist in beiden Versionen identisch.
Es hat zur Folge, dass alle Programmteile einer
DLL die im except eine Fehlerbehandlung mit GetLastError durchführen nicht mehr funktionieren.
Meine Frage ist nun:
1. kann man das irgendwie beheben, ohne die eigenen Quellen zu ändern?
2. Ist das in der aktuellen Version von Delphi immer noch so?
Gruß Bernd