![]() |
DLL-Zugriff und EAccessViolation
Hallo zusammen!
Ich bräuchte mal ein wenig seelischen Beistand von Euch. Irgendwie habe ich das dumme Gefühl, dass ich mich extrem verrannt habe. Ich möchte mir einen Wrapper für eine ![]() Das sagt die Doku: Zitat:
Code:
und hier meine Umsetzung in Delphi:
Private Declare Auto Function AUDIOFormatIsValidW Lib "AudioGenie2.dll" Alias "AUDIOFormatIsValid" () As System.Int16
Public Function AUDIOFormatIsValid() As System.Boolean Return CBool(AUDIOFormatIsValidW) End Function
Delphi-Quellcode:
Egal welchen Rückgabetyp ich für die DLL-Function verwende, ich bekomme immer eine Debugger-EAccessViolation-Exception "at address XYZ in 'DLL'. Read of address 00000000" in Zeile 14. Die DLL kann also geladen werden, der Export-Einsprungspunkt wird anscheinend auch gefunden.
function TAudioGenie2.AUDIOFormatIsValid: boolean;
type TAudioGenie2_AUDIOFormatIsValid = function: integer; stdcall; var Proc: TAudioGenie2_AUDIOFormatIsValid; Handle: THandle; begin Result:= False; Handle:= LoadLibrary(PChar(AudioGenie2dll)); if Handle <> 0 then begin @Proc := GetProcAddress(Handle, 'AUDIOFormatIsValid'); if @Proc <> nil then Result:= Proc = -1; FreeLibrary(Handle); end; end; Mache ich was falsch oder ist das womöglich ein Fehler in der DLL? |
Re: DLL-Zugriff und EAccessViolation
1. Ich würde als Rückgabewert eher WordBool nutzen
2. Du gibst StdCall an, aber ich finde nirgendwo einen entsprechden Hinweis, dass stdcall verwendet wird. |
Re: DLL-Zugriff und EAccessViolation
Mit WordBool funktioniert es auch nicht, selbe Exception.
StdCall benutze ich, weil ich (mittlerweile) diverse andere DLL-Zugriffe erfolgreich mit dieser Aufrufkonvention zum Laufen gebracht habe. Und ich gehe jetzt mal nicht davon aus, dass der DLL-Programmierer zwischen verschiedenen Konventionen wechselt. Edit: Kann es sein, dass meine Typendeklaration für die DLL-Function falsch ist?
Delphi-Quellcode:
Meine bisherigen "Erfolge" habe ich ausschließlich mit Funktionen und Prozeduren mit zu übergebenden Parametern erzielt.
type
TAudioGenie2_AUDIOFormatIsValid = function: integer; stdcall; |
Re: DLL-Zugriff und EAccessViolation
lasse mal das @ vor proc weg. ich weiß das es auch mit geht aber eventuell wurde das verhalten inzwischen mal wieder geändert. Früher war es notwenig und um die Adresse der Variablen zu bekommen war es nötig @@ zu schreiben. Dann war es so das man das @ schreiben konnte aber nicht musste (schließlich ist proc ja ein Pointer dem du den Wert zuweist wo hingesprungen werden muss). Vielleicht wurde es ja inzwischen an andere Programmiersprachen angepasst und ein einfaches vorangestelltes @ gibt jetzt wirklich die Adresse der Variablen zurück.
"Read of address 00000000" sagt das etwas von Adresse 0 (nil) gelesen wird. Wenn dein Einstiegspunkt also nil ist wäre das eine ursache (anstelle von "@Proc <> nil" besser "Assigned(Proc)"). Eine andere Möglichkeit wäre das in der DLL von dieser Adresse versucht wird zu lesen. Wäre das der Fall ist es vermutlich so das du vorher erst etwas initialisieren musst. Anhand des Funktionsnamen würde ich vermuten das du vorher eine Datei öffnen musst oder so, denn woher weiß er sonst worauf sich das AudioformatValid bezieht. |
Re: DLL-Zugriff und EAccessViolation
Bei solchen Fehlern hilt es mal mit dem CPU-Fenster in den Code reinzuschauen.
Manchmal findet man dort die Ursache recht schnell:
Delphi-Quellcode:
Da haben wir die Ursache. Und wie Sir schon meinte muss man anscheinend erstmal eine Datei laden oder irgendetwas ausführen, damit an der besagten Adresse eine gültige Adresse steht.
asm
mov ecx,[$1003547] //irgendeine feste Adresse -> ecx wird 0 mov eax,[ecx] //AV call ... end; Wenn ich allerdings in der Export-Table die Funktionen: DLLGetObjectClass DLLRegisterServer etc. lese, dann könnte dies auch ein COM-Object sein. Aber der Rest sieht nicht danach aus :gruebel: Edit: Da ist kein COM drin! Du musst vorher die Funktion AUDIOAnalyzeFile(Datei:Pchar) aufrufen. |
Re: DLL-Zugriff und EAccessViolation
Zuerstmal Danke euch allen!
@SirThornberry: mit oder ohne @, macht keinen Unterschied.
Delphi-Quellcode:
hat die gleichen Auswirkungen wie
if Assigned(Proc) then
Delphi-Quellcode:
.
if Proc <> nil then
@sirius: Ja, das CPU-Fenster. Das ist ganz sicher eine tolle Sache, wenn ich wüsste, wie man das richtig interpretiert und verwendet. Das Problem ist, dass bei dieser Exeption immer eine Anweisung mitten in NTDLL.RaiseException (oder so ähnlich) markiert wird; bringt mir in diesem Fall nicht sonderlich viel. Und mit dem Initialisieren habt Ihr vollkommen recht. AUDIOAnalyzeFile(Datei:Pchar) gehört zu den wenigen Funktionen welche (anscheinend) problemlos funktionieren, zumindest wird mir bei einem Aufruf dieser Funktion ein gültiger und auch richtiger Rückgabewert geliefert. Erst nach diesem erfolgreichen Aufruf versuche ich AUDIOFormatIsValid aufzurufen. Ich habe mal den Entwickler dieser DLL angeschrieben. Vielleicht weiß er ja, woran das liegt und was man da machen kann. |
Re: DLL-Zugriff und EAccessViolation
Du musst auch vor der Exception im CPU-Fenster gucken :zwinker:
Der Code bringt zumindest keine AV:
Delphi-Quellcode:
Und wenn ich aus dem "Datei:PChar" ein "Datei: PWideChar" mache, dann gibt die Funktion sogar true zurück (Proc1 liefert 1 und Proc2 -1)
function AUDIOFormatIsValid: boolean;
var Proc1: function(datei:pwidechar):integer; stdcall; Proc2: function: integer; stdcall; Handle: THandle; begin Handle:= LoadLibrary(PChar(AudioGenie2dll)); if Handle <> 0 then begin Proc1 := GetProcAddress(Handle, 'AUDIOAnalyzeFile'); Proc2 := GetProcAddress(Handle, 'AUDIOFormatIsValid'); Proc1('test.mp3'); Result:= Proc2 = -1; FreeLibrary(Handle); end; end; |
Re: DLL-Zugriff und EAccessViolation
Hallo
System.Int16 -> das ist 16bit, du nimmst aber 32bit SmallInt müsste richtig sein. Nur am Rande: GetProcAddress kann auch NIL zurückgegeben, das würde ich mal testen. Heiko |
Re: DLL-Zugriff und EAccessViolation
Zitat:
|
Re: DLL-Zugriff und EAccessViolation
Sirius, Dein Code funktioniert (nach ein paar Anpassungen)... :gruebel:
Jetzt muss ich nur noch den Fehler in meinem Code finden... obwohl ich auf den ersten Blick keinen großartigen Unterschied zu meinem Code sehe. :wall: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz