Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zugriffsverletzung beim Aufrufen einer eigenen DLL (https://www.delphipraxis.net/34296-zugriffsverletzung-beim-aufrufen-einer-eigenen-dll.html)

Thomas233 20. Nov 2004 17:43


Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Hallo,

ich habe ein Problem beim Verwenden meiner selbst geschrieben DLL in meinen Programm, und zwar handelt es sich um eine Zugriffsverletzung die beim Aufrufen einer Prozedur aus einer DLL entsteht.

Die Dll wird statisch ins Programm eingebunden. Sie parst eine Datei welche auf der Fesplatte vorhanden ist.

Ich habe DLLs bisher immer gemieden da ich immer dieses Zugriffsverletzungs-Problem mit jeder DLL die ich erstellt hatte gehabt habe.

Irgendwo scheine ich da immer einen Fehler zu machen obwohl ich nach einem Dll-Tutorial, welches ich bei Delphi-Source.de fand, vorgehe.

Wenn ich den Quellcode direkt in mein Programm einbinde (also nicht in die Dll auslagere sondern in eine Unit des Programmes) dann gibts keine Probleme, es kann also nur an der Dll selbst liegen !
Es ist auch egal welche Aufrufkonvention ich verwende, es kommt immer wieder eine Zugriffsverletzung.

Delphi-Quellcode:
// Quellcode der Dll
library gui;

uses
  SysUtils,
  Classes,
  d3d_sprite_gui in '..\..\..\d3d_sprite_gui.pas',
  d3d_input in '..\..\..\d3d_input.pas',
  dxhelp in '..\..\..\dxhelp.pas',
  d3dx9 in '..\..\..\d3dx9.pas',
  Direct3D9 in '..\..\..\Direct3D9.pas',
  DirectInput9 in '..\..\..\DirectInput9.pas',
  dxerr9 in '..\..\..\dxerr9.pas',
  DXFile in '..\..\..\DXFile.pas',
  d3d_sprite_textout in '..\..\..\d3d_sprite_textout.pas',
  d3d_sprite in '..\..\..\d3d_sprite.pas',
  uTools in '..\..\..\uTools.pas',
  StrUtils;

var CurPos:integer=-1;
    Sl:TStringlist;
    GuiDev:TD3DGui;
    EndPosofproc:integer;

{$R *.res}

procedure Gui_Add_Cmd(str:string);
begin
//...
end;

procedure Gui_Set_Cmd(str:string);
begin
//...
end;

procedure Gui_Cmd;
var i:integer;
begin
//...
end;

procedure Proc_Cmd(findproc:Shortstring);
var i:integer;
begin
//...
end;

procedure ParseGuiFromFile(_Gui:TD3DGui;filename:ShortString;menu:ShortString); pascal;
begin
GuiDev:=_Gui;
Sl:=TStringlist.Create;
Sl.LoadFromFile(filename);

Proc_Cmd(menu);

Sl.Free;
end;

exports
  ParseGuiFromFile;

begin

end.
Delphi-Quellcode:
//Deklaration
procedure ParseGuiFromFile(_Gui:TD3DGui;filename:ShortString;menu:ShortString); pascal;
//Implementierung
procedure ParseGuiFromFile(_Gui:TD3DGui;filename:ShortString;menu:ShortString); pascal; external 'data\dlls\gui.dll';
//Aufruf
ParseGuiFromFile(Gui,'data\scripts\gui\gui1.whs','GuiMainMenu');
Ich bin echt ratlos und so schön langsam fange ich an den ganzen Dll-Kram zu hassen :wall:

Wäre echt nett wenn einer mir einen Tipp zur Vermeidung des Problems geben könnte :wink:

Vielen Dank im Vorraus !

Liebe Grüße,
Thomas

jim_raynor 20. Nov 2004 19:23

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Du verwendest Strings, also musst du die Unit ShareMem sowohl in der DLL als auch im Programm als erstes einbinden.

Meflin 20. Nov 2004 19:41

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
verwende alternativ PChar, um dir das mitgeben der dll zu ersparen!

Thomas233 20. Nov 2004 21:11

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Hallo,

laut dem Dll-Experten kann auch ShortString statt eines normalen Strings verwendet werden um die Verwendung von Sharemem zu verhindern.

Nun habe ich alle ShortString-Übergabeparameter gegen PChar-Übergabeparameter ausgetauscht, geholfen hat es aber leider nichts :(


Liebe Grüße,
Thomas

Olli 29. Jul 2005 21:22

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Kannst du mal versuchen TD3DGui als var zu übergeben. Also quasi zu forcieren, daß der Pointer übergeben wird (alternativ const).

Wenn das nicht funktioniert, müßtest du bitte mal die DLL und die EXE anhängen. Dann würde ich mir das im Debugger mal anschauen.

Reinhold 29. Jul 2005 23:19

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Hallo Thomas,

Versuchs mal mit stdcall und nicht mit pascal.

Delphi-Quellcode:
// DLL
procedure ParseGuiFromFile(_Gui:TD3DGui;filename:ShortString;menu:ShortString); stdcall;

// Im Programm
// Interface
procedure ParseGuiFromFile(_Gui:TD3DGui;filename:ShortString;menu:ShortString); stdcall;
// Implementation
const
  DllName = 'data\dlls\gui.dll';

procedure ParseGuiFromFile; external DllName Name 'ParseGuiFromFile';
mfg
Reinhold

Olli 30. Jul 2005 00:00

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Zitat:

Zitat von Reinhold
Versuchs mal mit stdcall und nicht mit pascal.

Sollte doch keinen Unterschied machen, da er ja sowohl DLL als auch Programm schreibt. Und relevant ist nur, daß die gleichen Aufrufkonventionen an beiden Stellen benutzt werden.

jbg 30. Jul 2005 10:29

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
pascal ist aber veraltet. Es wurde unter Win16 benutzt, aber dann durch stdcall bei der Win32API ersetzt (sind aber kompatibel, trotzdem sollte man sie nicht mischen).

Olli 30. Jul 2005 12:25

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Zitat:

Zitat von jbg
pascal ist aber veraltet. Es wurde unter Win16 benutzt, aber dann durch stdcall bei der Win32API ersetzt (sind aber kompatibel, trotzdem sollte man sie nicht mischen).

Das ist leider nicht korrekt. Die beiden sind nicht kompatibel. Schau mal unter Delphi-Referenz durchsuchenCalling conventions nach.
Code:
Directive Param order   Clean-up  Passes parameters in registers?
--------- -----------    --------   -------------------------------
register Left-to-right Routine   Yes
[color=red]pascal   [b]Left-to-right[/b] Routine   No[/color]
cdecl    Right-to-left Caller    No
[color=red]stdcall  [b]Right-to-left[/b] Routine   No[/color]
safecall Right-to-left Routine   No
Ich glaube du verwechselst hier jenes PASCAL (ein Präprozessor-Define in C), welches identisch ist mit dem jetzigen WINAPI (#define WINAPI __stdcall). Hat allerdings nichts mit den gleichnamigen Aufrufkonventionen in Delphi gemein. PASCAL wurde tatsächlich unter Windows 16bit benutzt.

Die Hauptsache ist eben, sie nicht zu mischen, wie ich oben ja schon schrieb. Macht der Fragesteller aber nicht, daher sollte irrelevant sein, welche er benutzt. Zumal dies bei einer DLL die mglw. nie in einem anderen Programm wiederverwendet wird (immerhin wird ein Objektzeiger übergeben!) sowieso irrelevant ist (man muß also nicht krampfhaft stdcall benutzen).

SirThornberry 30. Jul 2005 12:30

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
zudem ist die standardaufruf-convention "Register" und nicht "pascal"

Thomas233 15. Aug 2005 22:05

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Hmmm...mit Delhpi 2005 hab ich jetzt nach ersten Test eigentlich keine Probleme mehr damit. Fragt mich nicht warum, vielleicht war`s ja ein Bug in Delphi 6. Naja, bin ich ja fast schon gar nicht mehr gewohnt Dlls zu benutzen, wird mal wieder Zeit ;-)

Trotzdem Dank für eure Hilfe. Werde darauf zurück kommen falls es doch noch zu Problemen kommt !

Olli 15. Aug 2005 22:12

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Zitat:

Zitat von Thomas233
Hmmm...mit Delhpi 2005 hab ich jetzt nach ersten Test eigentlich keine Probleme mehr damit.

Zitat:

Zitat von Olli
Sollte doch keinen Unterschied machen, da er ja sowohl DLL als auch Programm schreibt.

Zitat:

Zitat von Thomas233
Naja, bin ich ja fast schon gar nicht mehr gewohnt Dlls zu benutzen, wird mal wieder Zeit ;-)

Darf ich das bezweifeln? ... :mrgreen: - es kann keine Win32-EXE-Dateien geben, die keinen Import haben. Zumindest nicht auf der NT-Plattform.

Thomas233 30. Aug 2005 22:11

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Danke, erledigt ! :-)

Mit freundlichen Grüßen,
Thomas Tschofenig

NicoDE 30. Aug 2005 22:34

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Zitat:

Zitat von Olli
es kann keine Win32-EXE-Dateien geben, die keinen Import haben. Zumindest nicht auf der NT-Plattform.

Das betrifft nur Windows 2000 (alle anderen Loader laden die kernel32.dll bevor sie sie aufrufen :)).

Olli 30. Aug 2005 22:47

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Zitat:

Zitat von NicoDE
Zitat:

Zitat von Olli
es kann keine Win32-EXE-Dateien geben, die keinen Import haben. Zumindest nicht auf der NT-Plattform.

Das betrifft nur Windows 2000 (alle anderen Loader laden die kernel32.dll bevor sie sie aufrufen :)).

Ich denke nicht. Ich habe es von NT 4.0 (ohne SP) bis Windows 2003 (ohne SP) ausgetestet und es lief nirgends!!! Weder wenn als CUI, noch wenn als GUI kompiliert. Kannst du mal anhängen, was bei deinen Tests auch auf Windows NT 4.0, XP und 2003 lief?!

NicoDE 30. Aug 2005 23:00

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
http://www.sistemo.com/snippets/NoImport.zip

Olli 31. Aug 2005 08:17

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Dann liegt es wohl auch noch an der Methode, wie man die Adresse einer API ermittelt. In meiner EXE die 9xer von dir geht tatsächlich auf W2K3, komischerweise meine PEB-Methode (nicht hardkodiert!) nicht - mit einem Import geht's dann wieder ...

NicoDE 31. Aug 2005 14:15

Re: Zugriffsverletzung beim Aufrufen einer eigenen DLL
 
Zitat:

Zitat von Olli
Dann liegt es wohl auch noch an der Methode, wie man die Adresse einer API ermittelt.

Ich denke, dass es am Layout des Images liegt (Anzahl/Anordnung/Vorhandensein von Segmenten).
Wir werden off-topic :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:19 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz