Entwickler-Ecke
Algorithmen, Optimierung und Assembler - Fehler beim Aufrufen einer DLL-Funktion bei Optimierung
jkits - Mi 20.10.04 16:22
Titel: Fehler beim Aufrufen einer DLL-Funktion bei Optimierung
Hallo Delphi Experten,
Ich habe folgendes Problem:
Mein Programm benutzt eine Dll.
Wenn ich in den Compileroptionen die Optimierung ausgeschaltet habe, funktioniert alles einwandfrei.
Mit eingeschalteter Optimierung läuft das Programm genau bis zum ersten Aufruf einer DLL-Funktion und bricht dann ab. (Die Adresse der Funktion ist dann $FFFFFFFF).
Woran liegt das? Wie kann man das umgehen?
PS: die funktionen werden etwas seltsam eingebunden:
Delphi-Quelltext
1: 2: 3: 4:
| OpenMPEG2File:=GetProcAddress(DLLHandle,'?OpenMPEG2File@@YGHPAD_J1@Z'); if not Assigned(OpenMPEG2File) then Exit; ... result := true; |
Gruß jkITs
jasocul - Mi 20.10.04 16:27
Ich vermute, dass die Optimierung feststellt, dass du am Schluss result immer auf true hast. damit ist der ganze Kram davor "Unsinn" für den Optimierer und wird entfernt.
jkits - Mi 20.10.04 16:32
Dann würde er ja die Exit Anweisung übersehen. Das glaube ich nicht. Davor ist result := false.
jasocul - Mi 20.10.04 16:36
Könntest Recht haben. Hast du das schon mal debugged?
Ich verlasse mich schon lange nicht mehr auf assigned. Eventuell bekommst du durch die Optimierung was falsches bei der ProcAddress zurück. Wenn das dann nicht sicher nil ist, macht assigned Blödsinn. Dadurch greift das Exit nicht mehr und das wars.
Mach doch mal direkt nach der Adress-Zuweisung ein Test, ob du auch was sinnvolles bekommen hast.
jkits - Mi 20.10.04 16:42
jasocul hat folgendes geschrieben: |
Ich verlasse mich schon lange nicht mehr auf assigned. |
Gute Idee, das werde ich mal checken. Mit assigned hatte ich auch schon Probleme.
Gruß jkITs
Motzi - Mi 20.10.04 18:17
jkits hat folgendes geschrieben: |
jasocul hat folgendes geschrieben: | Ich verlasse mich schon lange nicht mehr auf assigned. |
Gute Idee, das werde ich mal checken. Mit assigned hatte ich auch schon Probleme. |
Kann ich mir nicht vorstellen.. was willste denn anders machen? Assigned macht auch nichts andres als den Pointer auf nil zu prüfen, nicht mehr und nicht weniger..
AndyB - Mi 20.10.04 18:50
jkits hat folgendes geschrieben: |
Gute Idee, das werde ich mal checken. Mit assigned hatte ich auch schon Probleme. |
Dann würde ich dir vorschlagen, deinen Code vor (zeitlicher Ablauf) dem Assigned zu überprüfen.
Zitat: |
Delphi-Quelltext 1: 2: 3: 4:
| OpenMPEG2File:=GetProcAddress(DLLHandle,'?OpenMPEG2File@@YGHPAD_J1@Z'); if not Assigned(OpenMPEG2File) then Exit; ... result := true; | |
Bist du dir sicher, dass das bei "if not Assigned..." einen Fehler generiert? Ich denke eher (kann ja nur annehmen) dass es bei "..." passiert, im Speziellen vor oder während oder nach dem Aufruf der Funktion.
jasocul - Mi 20.10.04 18:55
Motzi hat folgendes geschrieben: |
Kann ich mir nicht vorstellen.. was willste denn anders machen? Assigned macht auch nichts andres als den Pointer auf nil zu prüfen, nicht mehr und nicht weniger.. |
Weiß ich wohl. Aber was ist mit dem Pointer, wenn eine ungültige Adresse zurückkommt. Dann funktioniert Assigned in diesem Fall nicht mehr. Was der Optimierer dort nun genau macht, weiß ich jedenfalls nicht. Vielleicht wird der Pointer nicht initialisiert? Dann ist er nicht nil ...
jasocul - Mi 20.10.04 18:57
AndyB hat folgendes geschrieben: |
Bist du dir sicher, dass das bei "if not Assigned..." einen Fehler generiert? Ich denke eher (kann ja nur annehmen) dass es bei "..." passiert, im Speziellen vor oder während oder nach dem Aufruf der Funktion. |
Einer der Gründe, warum ich empfohlen habe, dort mal zu debuggen.
AndyB - Mi 20.10.04 19:02
jasocul hat folgendes geschrieben: |
Dann funktioniert Assigned in diesem Fall nicht mehr. |
Doch es funktioniert. GetProcAddress liefert entweder nil oder die Adresse. Dazwischen gibt es nichts. Und der Optimierer ist da nicht schuld, der scheint nur einen nicht so offensichtlichen Fehler im Programm zum Vorschein zu bringen, da er einige Annahmen über die CPU Register-Inhalte macht, die normalerweise (eigentlich immer) die Annahmewert enthalten, außer es passierte irgendwo ein (Programmier-)Fehler.
Zitat: |
Vielleicht wird der Pointer nicht initialisiert? Dann ist er nicht nil ... |
Hä? Die Zuweisung findet entweder statt (initialiseren des Zeigers) oder sie findet nicht statt, dann ist der einzige Grund eine Exception, die aber auch das Ausführen des Folgecodes verhindert.
Ich glaube eher, dass die falsche Aufrufkonvention benutzt wird. Schon mal was von
__fastcall beim MSVC gehört? Das entspricht nicht wirklich dem
register von Delphi.
jasocul - Mi 20.10.04 19:13
AndyB hat folgendes geschrieben: |
GetProcAddress liefert entweder nil oder die Adresse.
...
Ich glaube eher, dass die falsche Aufrufkonvention benutzt wird. Schon mal was von __fastcall beim MSVC gehört? Das entspricht nicht wirklich dem register von Delphi. |
Nehme alles zurück und behaupte das Gegenteil. :wink:
Ich glaube dann aber nicht, dass das Einschalten der Optimierung zum Fehler geführt hat. Das dürfte dann wohl eher zufällig mit einer Programmänderung zusammenhängen.
Warten wir mal ab, was dabei rauskommt.
AndyB - Mi 20.10.04 19:21
jasocul hat folgendes geschrieben: |
Ich glaube dann aber nicht, dass das Einschalten der Optimierung zum Fehler geführt hat. |
Das Einschalten hat "nur" dazu geführt, dass der Fehler entdeckt wurde. __fastcall (vom MSVC) benutzt das ECX Register als ersten Parameter. Der Rest wird über den Stack übergeben. Wenn nun durch die Optimierung ein Wert in das ECX Register geschrieben wird, mit dem die Funktion "nichts anfangen kann", kommt es zu einer Schutzverletzung.
jasocul - Mi 20.10.04 19:26
Danke für den Hinweis. Wieder was dazu gelernt.
jkits - Do 21.10.04 11:52
Hallo,
erst mal vielen Dank, dass sich so viele für das Problem interessieren.
Halle gestern leider nicht viel Zeit zu Testen.
- der Aufruf liefert einen gültigen Pointer, beim weiterverfolgen im Debugger hats mir den Rechner zerlegt (+ WAF-timeout :wink: )
- nach dem geposteten code, also bei ... werden nur weitere Funktionsadressen auf die gleiche Weise geholt.
so ist die Funktion in der DLL .h definiert:
Quelltext
1:
| DLLExport(int) OpenMPEG2File(char *FileName,int64 Offset=0,int64 Size=-1); |
Ich muss also erst ausführlicher testen
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!