Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi DLL verursacht Zugriffsverletzung in MDI-Anwendung (https://www.delphipraxis.net/93556-dll-verursacht-zugriffsverletzung-mdi-anwendung.html)

NetSonic 7. Jun 2007 12:52


DLL verursacht Zugriffsverletzung in MDI-Anwendung
 
Ich habe folgendes Problem:

Ich binde eine DLL mit Windows API-Funktionen in eine Anwendung, die nur aus einem Hauptformular besteht wie folgt ein:

Delphi-Quellcode:
implementation

{$R *.DFM}

//Ansterungsfunktionen aus DLL
function StartWatchdog(Timeout: PChar): Boolean; stdcall; external 'wdt_io_dll.dll';
function StopWatchdog(): Boolean; stdcall; external 'wdt_io_dll.dll';
function RestartWatchdog(): Boolean; stdcall; external 'wdt_io_dll.dll';
function IO_Write(Value: PChar): Boolean; stdcall; external 'wdt_io_dll.dll';
function IO_Read(): PChar; stdcall; external 'wdt_io_dll.dll';

Der Aufruf erfolg z.B. mit dieser Funktion:

Delphi-Quellcode:
procedure TfrmMain.btnWriteClick(Sender: TObject);
begin
     if (IO_Write(PChar(txtOutput.Text)) = false) then
     begin
          MessageDlg('Fehler, kein (gültiges) Handle!', mtWarning, [mbOK], 0);
     end;
end;
Das klappt auch wunderbar. Nun habe ich noch eine Anwendung, die als MDI-Applikation erstellt wurde. Von einem dieser Child-Fenster, die im laufenden Betrieb erzeugt werden, möchte ich nun auch diese Funktionen aus der DLL nutzen. Das ganze habe ich wie folgt in das MDI-Child eingebunden:

Delphi-Quellcode:
implementation

uses frmMainUnit;

{$R *.DFM}

//Ansterungsfunktionen aus DLL importieren
function StartWatchdog(Timeout: PChar): Boolean; stdcall; external 'dll\wdt_io_dll.dll';
function StopWatchdog(): Boolean; stdcall; external 'dll\wdt_io_dll.dll';
function RestartWatchdog(): Boolean; stdcall; external 'dll\wdt_io_dll.dll';
function IO_Write(Value: PChar): Boolean; stdcall; external 'dll\wdt_io_dll.dll';
function IO_Read(): PChar; stdcall; external 'dll\wdt_io_dll.dll';
(Die DLL liegt im Unterordner "dll" im Programmverzeichnis, Pfadänderungen beheben das Problem auch nicht!)
und rufe es so auf...

Delphi-Quellcode:
procedure TfrmRun.btnEinzelbetriebClick(Sender: TObject);
begin
     //Spannung einschalten
     if (IO_Write(PChar('2')) = true) then
     begin
          imgSpannung.Picture.LoadFromFile(ExtractFileDir(Application.ExeName) + '\sys\led_green.jpg');
     end
     else begin
          imgSpannung.Picture.LoadFromFile(ExtractFileDir(Application.ExeName) + '\sys\led_red.jpg');
          StatusLogWrite('Keine Spannung auf dem Kreis!', 'Info');
     end;
     Application.ProcessMessages;
     //Signal einschalten
     if (IO_Write(PChar('4')) = true) then
     begin
          imgSignal.Picture.LoadFromFile(ExtractFileDir(Application.ExeName) + '\sys\led_green.jpg');
     end
     else begin
          imgSignal.Picture.LoadFromFile(ExtractFileDir(Application.ExeName) + '\sys\led_red.jpg');
          StatusLogWrite('Kein Signal auf dem Kreis!', 'Info');
     end;
end;
Jedoch bekomme ich immer eine Zugriffsverletzung und die "IO_Writes" werden nicht ausgeführt, obwohl die Anwendung sonst gut läuft und ich die Einbindung von der oberen Anwendung übernommen habe. Liegt das evtl. daran, dass ich MDI-Childs nutze? Gibt es da besonderheiten beim Einbinden von DLL's?

Gruß, NetSonic

hoika 7. Jun 2007 13:12

Re: DLL verursacht Zugriffsverletzung in MDI-Anwendung
 
Hallo,

gaaanz sicher, dass der Aufruf gleich ist ?
Das PChar('2') steht wirklich auch bei der anderen App ?

Wo genau kommt denn die Schutzverletzung,
in der Dll ? nach IOWrite.
Was macht IOWrite mit "Value",
nur prüfen, was drinsteht oder auch was reinschreiben.


Heiko

NetSonic 7. Jun 2007 13:30

Re: DLL verursacht Zugriffsverletzung in MDI-Anwendung
 
Zugriffsverletzung kommt beim Aufruf von IO_Write aber im Programm, nicht in der DLL. Er meldet also Fehler *** in "pogramm.exe".
Der Funktion "IO_Write" wird mit Value ein Wert übergeben, der an einen digitalen I/O-Port auf einem Industrie-Mainboard gesendet wird, um eine Bewässerungsanlage zu steuern. Zurückgegeben wird TRUE oder FALSE, je nachdem ob die Anweisung erfolgreich übermittelt werden konnte, oder nicht. Also müsste er mir FALSE zurückgeben, wenn es einen Fehler gibt, stattdessen bekomme ich jedoch die Zugriffsverletzung!

Der Aufruf in meinem anderen Programm sieht so aus:
(Da kommt der Wert für VALUE aus einer Textbox)

Delphi-Quellcode:
if (IO_Write(PChar(txtOutput.Text)) = false) then
begin
     MessageDlg('Fehler, kein (gültiges) Handle!', mtWarning, [mbOK], 0);
end;

hoika 7. Jun 2007 13:58

Re: DLL verursacht Zugriffsverletzung in MDI-Anwendung
 
Hallo,

dann packe die '2' mal in eine lokale Variable
Delphi-Quellcode:
var
  szTemp: array[0..1] of Char;
begin
  StrPCopy(szTemp, '2');
und übergib diese Variable direkt (type cast auf PChar ist nicht notwendig)

oder
Delphi-Quellcode:
var
  sTemp: String;
begin
  sTemp:= '2';
Übergabe als PChar(sTemp)


Heiko

Muetze1 7. Jun 2007 14:22

Re: DLL verursacht Zugriffsverletzung in MDI-Anwendung
 
Zur Erklärung bei hoika's Beispiel: einzelne Zeichen als konstanten String übergeben bei einem PChar() typecast verwandelt Delphi in einen entsprechenden Pointer mit dem Wert und nicht mit dem Ziel.

Sprich: PChar('2') ist das gleiche wie Pointer(Ord('2')). Dadurch kommt dann die AV, weil die Adresse einfach nur Müll ist...

NetSonic 11. Jun 2007 14:00

Re: DLL verursacht Zugriffsverletzung in MDI-Anwendung
 
Also erstmal Danke für Eure Tipps.
Wenn ich das so mache, wie "hoika" es vorgeschlagen hat und eine lokale Variable nutze, dann geht es... wenn man genau darüber nachdenkt macht das auch Sinn! :gruebel:
Danke für Deine Erklärung dazu "Muetze1"...

Schönen "sonnigen" Tag noch! :mrgreen:


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