Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi DLL Funktionsaufruf (https://www.delphipraxis.net/97864-dll-funktionsaufruf.html)

Neutral General 17. Aug 2007 14:24


DLL Funktionsaufruf
 
Hi,

Ich rufe eine ganz simple, aus einer DLL importierte procedure auf. Sie liefert mir (glaube ich) korrekte Daten aber danach bekomme ich eine Zugriffsverletzung.


Delphi-Quellcode:
type
  VERSIONINFO = packed record
    cbSize: DWORD;
    dwMajorVersion: DWORD;
    dwMinorVersion: DWORD;
    dwBuildNumber: DWORD;
    dwPlatformID: DWORD;
  end;
  PVERSIONINFO = ^VERSIONINFO;

function DllGetVersion(out pdvi: PVERSIONINFO): HRESULT; stdcall; external 'cabinet.dll';

implementation

procedure TForm1.Button1Click(Sender: TObject);
var x: PVERSIONINFO;
begin
  New(x);
  x^.cbSize := SizeOf(VERSIONINFO);
  DLLGetVersion(x);
  ShowMessage(IntToStr(x.dwMajorVersion) + '.'+ IntToStr(x.dwMinorVersion));
  Dispose(x);
end;
Das Record ist eigentlich 100%ig richtig. Die Version sieht original so aus:

Code:
HRESULT DllGetVersion(DLLVERSIONINFO* pdvi)
Mache ich da was falsch? Mit FreeMem statt Dispose hab ichs auch schon probiert. Oder ich hab den Speicher gar nicht freigegeben aber das nutzt auch nichts -.-

Gruß
Neutral General

angos 17. Aug 2007 14:34

Re: DLL Funktionsaufruf
 
Hallo Michael,


ich hatte hier letztens ein ähnliches Problem.... Bei mir kam ebenfalls nach dem Aufruf der Funktion eine AV. Bei mir lag es daran, dass ich ShareMem nur in einem der beiden Projekte (Programm und DLL) aktiviert hatte. Prüfe das mal auf diese Gegebenheit hin... ich hab da auch lange suchen müssen und fast nen Brechreiz bekommen, wo ich das herausgefunden hatte -.-

Gruß

sirius 17. Aug 2007 14:35

Re: DLL Funktionsaufruf
 
Bist du dir mit stdcall sicher?

Neutral General 17. Aug 2007 14:36

Re: DLL Funktionsaufruf
 
Mh das ganze ist einfach kein out-Parameter... Das stand irgendwo fälschlicherweise in ner Dokumentation... Hat sich erledigt. Danke :)

Muetze1 17. Aug 2007 14:45

Re: DLL Funktionsaufruf
 
Richtig, weil sonst der mit New() angelegte Speicher von dem von der DLL zurück gegebenen Pointer überschrieben wird und Dispose() einen fremden Speicher freigeben muss. Dieser ist sogar höchstwahrscheinlich sogar statisch in der DLL vorhanden für die Struktur und von daher stößt das Dispose() bzw. dem MemoryManager ganz sauer auf.

Neutral General 17. Aug 2007 14:54

Re: DLL Funktionsaufruf
 
Gibt was neues:

Delphi-Quellcode:
function DllGetVersion(var pdvi: DLLVERSIONINFO): HRESULT; stdcall; external 'cabinet.dll';
so muss es sein. Mein Aufruf im Moment:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var x: DLLVERSIONINFO;
begin
  FilLChar(x,SizeOf(DLLVERSIONINFO),0);
  x.cbSize := SizeOf(DLLVERSIONINFO);
  DLLGetVersion(x);
  ShowMessage(IntToStr(x.dwMajorVersion) + '.'+ IntToStr(x.dwMinorVersion));
end;
DLLGetVersion liefert mir $12F618. GetLastError liefert mir "Alles in Ordnung". Im Idealfall soll DLLGetVersion S_OK ($00000000) zurückliefern. Jedoch finde ich auch sonst nichts was $12F618 entspricht. Angezeigt wird mir nämlich Version 0.0 (was wohl sehr wahrscheinlich von meinem FillChar kommt......)

Gruß
Neutral General

sirius 17. Aug 2007 15:28

Re: DLL Funktionsaufruf
 
Zitat:

Zitat von Neutral General
DLLGetVersion liefert mir $12F618. GetLastError liefert mir "Alles in Ordnung". Im Idealfall soll DLLGetVersion S_OK ($00000000) zurückliefern. Jedoch finde ich auch sonst nichts was $12F618 entspricht. Angezeigt wird mir nämlich Version 0.0 (was wohl sehr wahrscheinlich von meinem FillChar kommt......)

Wie liefert dir DLLGetVersion $12F618 (sieht übrigens nach einer StackAdresse aus)
Wie, und was wird dir wo angezeigt? Ich verstehe dich nicht :cry:

Neutral General 17. Aug 2007 15:53

Re: DLL Funktionsaufruf
 
Zitat:

Zitat von sirius
Zitat:

Zitat von Neutral General
DLLGetVersion liefert mir $12F618. GetLastError liefert mir "Alles in Ordnung". Im Idealfall soll DLLGetVersion S_OK ($00000000) zurückliefern. Jedoch finde ich auch sonst nichts was $12F618 entspricht. Angezeigt wird mir nämlich Version 0.0 (was wohl sehr wahrscheinlich von meinem FillChar kommt......)

Wie liefert dir DLLGetVersion $12F618 (sieht übrigens nach einer StackAdresse aus)
Wie, und was wird dir wo angezeigt? Ich verstehe dich nicht :cry:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var x: DLLVERSIONINFO;
begin
  FilLChar(x,SizeOf(DLLVERSIONINFO),0);
  x.cbSize := SizeOf(DLLVERSIONINFO);
  ShowMessage(IntToHex(DLLGetVersion(x),6));
  ShowMessage(SysErrorMessage(GetLastError));
  ShowMessage(IntToStr(x.dwMajorVersion) + '.'+ IntToStr(x.dwMinorVersion));
end;
Zitat:

---------------------------
Cabtestapp
---------------------------
12F618
---------------------------
OK
---------------------------

Zitat:

---------------------------
Cabtestapp
---------------------------
Der Vorgang wurde erfolgreich beendet
---------------------------
OK
---------------------------
Zitat:

---------------------------
Cabtestapp
---------------------------
0.0
---------------------------
OK
---------------------------
Alles klar? :mrgreen:

hoika 17. Aug 2007 16:22

Re: DLL Funktionsaufruf
 
Hallo,

wie Neutrag General zeigt,
ist es am einfachsten die Deklaration der Dll-Methode zu ändern.

Delphi-Quellcode:
type
  TRec = record
  end;
  PRec = ^TRec;

procedure Foo1(var Rec: TRec);
procedure Foo2(PRec: TRec);
Foo1 und Foo2 sind das praktisch gleiche, Foo1 ist aber einfacher zu handhaben,
weil du keinen Zeiger benutzen musst.


Heiko

Neutral General 17. Aug 2007 16:32

Re: DLL Funktionsaufruf
 
Ehm ich sollte vielleicht erwähnen das die DLL nicht mir "gehört". Ich hab den Quellcode der DLL nicht... Ich kann mir also nicht aussuchen wie ich das ganze deklariere. Kann mir jemand sagen was jetzt noch schief läuft? (Siehe meinen vorherigen oder vorvorherigen Post).

Gruß
Neutral General

Robert Marquardt 17. Aug 2007 16:34

Re: DLL Funktionsaufruf
 
Versuch mal ohne packed zu deklarieren. Wenn das nicht hilft mach ein Dummy-Element (DWORD) hinten ins Record. MS Visual Studio arbeitet inzwischen gerne mit einem Record-Alignment von 8. Das Record muss also wahrscheinlich auf 24 statt 20 Bytes aufgeblasen werden.

@hoika, Tippfehler: es muss "procedure Foo2(PRec: PRec);" heissen.

sirius 17. Aug 2007 16:36

Re: DLL Funktionsaufruf
 
Wenn es sich um die DLL von Windows handelt, versuche mal folgendes Record:
Delphi-Quellcode:
  VERSIONINFO = packed record
    cbSize: DWORD;
    dwNULL1: DWORD;
    dwNULL2: DWORD;
    wMinorVersion: WORD;
    wMajorVersion: WORD;
    wBuildNumber: WORD;
    wPatchLevel: WORD;
  end;

Neutral General 17. Aug 2007 16:37

Re: DLL Funktionsaufruf
 
Zitat:

Zitat von Robert Marquardt
Versuch mal ohne packed zu deklarieren. Wenn das nicht hilft mach ein Dummy-Element (DWORD) hinten ins Record. MS Visual Studio arbeitet inzwischen gerne mit einem Record-Alignment von 8. Das Record muss also wahrscheinlich auf 24 statt 20 Bytes aufgeblasen werden.

+ dword - packed
+ dword + packed
- dword + packed
- dword - packed

klappt alles nicht. :(

@Sirius: In MSDN stehts anders, in meiner Doku stehts anders ... Aber deine Version klappt :wall: Was soll ich jetzt davon halten? -.-

sirius 17. Aug 2007 16:48

Re: DLL Funktionsaufruf
 
Liste der Anhänge anzeigen (Anzahl: 1)
Welche msdn hast du denn? Bei mir gibts da nur für die shell32 genau deine Spezic. Für die cabinet habe ich auf die schnelle keine einzige Info gefunden.
Ich habe nur probiert, siehe Anhang.
Übrigens: Das Funktionsergebnis kannste in den Skat drücken.

Neutral General 17. Aug 2007 16:52

Re: DLL Funktionsaufruf
 
Hi,

Also hatte in Google gesucht und bin dann auf der MSDN Seite gelandet.

Zitat:

Übrigens: Das Funktionsergebnis kannste in den Skat drücken.
in den Skat (?) drücken (?) ?

Die Muhkuh 17. Aug 2007 16:56

Re: DLL Funktionsaufruf
 
Ich denk mal, dass ist das gleiche, dass kannste Dir irgendwo anders hinschieben :mrgreen:

Neutral General 17. Aug 2007 16:57

Re: DLL Funktionsaufruf
 
Zitat:

Zitat von Die Muhkuh
Ich denk mal, dass ist das gleiche, dass kannste Dir irgendwo anders hinschieben :mrgreen:

:idea: :mrgreen:

Edit: "Skat drücken" kenn ich aber ich hab gedacht vielleicht ist das irgendwie für irgendwas ein Fachausdruck :oops: :wall:

sirius 17. Aug 2007 17:05

Re: DLL Funktionsaufruf
 
Kinners habt ihr nie Skat gespielt? In den Skat drückt man Karten, die man nicht braucht. :spin2:

Ähm, General, die url ist ... fehlerhaft.

Neutral General 17. Aug 2007 17:23

Re: DLL Funktionsaufruf
 
Mh bei mir geht die.. Alternativ: Bei Google suchenDLLVERSIONINFO. Erstes Ergebnis.

Klar hab ich Skat gespielt und ich spiels immernoch aber das Sprichwort kenn ich nicht also hab ichs irgendwie für nen Fachausdruck gehalten :gruebel: :mrgreen:

sirius 17. Aug 2007 18:14

Re: DLL Funktionsaufruf
 
Hmm, sehr schöne Aussage da:
Zitat:

Zitat von msdn
This function is not an API. It is exported by name from each DLL that implements it. Currently, most of the Windows Shell and common controls DLLs implement DllGetVersion.

Und andere DLLs implemtierwen diese Funktion anscheinend anders. Fragt sich nur wie lange...


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:54 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