Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi IOCTL von C nach Delphi portieren (https://www.delphipraxis.net/91832-ioctl-von-c-nach-delphi-portieren.html)

NetSonic 11. Mai 2007 08:50

Re: IOCTL von C nach Delphi portieren
 
Das ganze sieht jetzt so aus, allerdings mosert der kompiler...

Delphi-Quellcode:
type
  PWDTPARAM = ^WDTPARAM;
  WDTPARAM = record
    timeout: Byte;
    data_b: Byte;
  end;

const
     WDT_TYPE = $88B9; //35001;

     WDT_DEVICE   = '\\.\WDT_DEVICE';
     WDT_DEVICE_NAME = '\Device\WDT_DEVICE';
     WDT_DOS_DEVICE_NAME = '\DosDevices\WDT_DEVICE';

     IOCTL_SYS_DIO_WRITE = (WDT_TYPE shl 16) or (2 shl 14) or ($805 shl 2) or 0;
     IOCTL_SYS_WDT_STOP = (WDT_TYPE shl 16) or (2 shl 14) or ($802 shl 2) or 0;
var
  hDIO: THandle;
  cParam: WDTPARAM;
  nReturn: DWORD;

procedure TForm1.Button1Click(Sender: TObject);
begin
     hDIO := CreateFile(WDT_DEVICE, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR
                    FILE_SHARE_WRITE, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL OR
                    FILE_FLAG_NO_BUFFERING, 0);
     cParam.data_b := IntToStr('$' + Edit1.Text);
     DeviceIoControl(hDIO, IOCTL_SYS_DIO_WRITE, @cParam, SizeOf(cParam), nil, 0, nReturn, NULL);
end;
Er sagt hier...
Zitat:

cParam.data_b := IntToStr('$' + Edit1.Text);
"Es gibt keine überladene Version von 'IntToStr', die man mit diesen Argumenten aufrufen kann", was man vielleicht so lösen könnte:

Delphi-Quellcode:
cParam.data_b := StrToInt('$' + Edit1.Text);
???? :gruebel:

und hier...
Zitat:

DeviceIoControl(hDIO, IOCTL_SYS_DIO_WRITE, @cParam, SizeOf(cParam), nil, 0, nReturn, NULL);
immer noch: "Konstantenausdruck verletzt untere Grenzen" sowie "Inkompatible Typen: 'Variant' und 'POverlapped'" :?:

Wie ich vorhin auf so einen Quatsch gekommen bin, ist mir selber ein Rätsel... Vielleicht liegt es daran, dass mir dieser Bereich noch mehr als neu ist. Nur leider komme ich nicht darum herum. Vorher habe ich die notwendigen Hardware-Zugriffe per USB und dem Zugriff auf eine DLL gelöst, nur müssen wir jetzt leider diese auf dem Mainboard integrierten IO-Ports nutzen und dafür gibt es leider keine DLL oder ähnliches. Es geht alles nur über die Windows-API und die DeviceIOControl-Aufrufe... Leider!

Robert Marquardt 11. Mai 2007 09:04

Re: IOCTL von C nach Delphi portieren
 
Falsche Funktion benutzt. Es soll StrToInt sein und nicht IntToStr. :oops:
Delphi-Quellcode:
cParam.data_b := Byte(StrToInt('$' + Edit1.Text));
Umzutypen sollte vielleicht auch noetig sein.
Delphi-Quellcode:
DeviceIoControl(hDIO, IOCTL_SYS_DIO_WRITE, @cParam, SizeOf(cParam), nil, 0, nReturn, nil);
Zuviel C in letzter Zeit.
Delphi-Quellcode:
IOCTL_SYS_DIO_WRITE = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($805 shl 2) or 0);
Das forciert den richtigen Typ.

NetSonic 11. Mai 2007 09:27

Re: IOCTL von C nach Delphi portieren
 
Strike! Jetzt klappt es. Hab den Hardware-Zugriff auch eben getestet und es funktioniert wie gewünscht! Danke für die tolle Unterstützung! :thumb:

Nachfolgend nochmal der komplette Quellcode, bzw. korrekte Abschnitt:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TfrmMain = class(TForm)
    gboxWatchdog: TGroupBox;
    gboxIOOperations: TGroupBox;
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type
  PWDTPARAM = ^WDTPARAM;
  WDTPARAM = record
    timeout: Byte;
    data_b: Byte;
  end;

const
     WDT_TYPE = $88B9; //35001;

     WDT_DEVICE   = '\\.\WDT_DEVICE';
     WDT_DEVICE_NAME = '\Device\WDT_DEVICE';
     WDT_DOS_DEVICE_NAME = '\DosDevices\WDT_DEVICE';

     IOCTL_SYS_WDT_SET_TIMEOUT = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($800 shl 2) or 0);
     IOCTL_SYS_WDT_START = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($801 shl 2) or 0);
     IOCTL_SYS_WDT_STOP   = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($802 shl 2) or 0);
     IOCTL_SYS_WDT_RESTART = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($803 shl 2) or 0);
     IOCTL_SYS_DIO_READ   = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($804 shl 2) or 0);
     IOCTL_SYS_DIO_WRITE = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($805 shl 2) or 0);

var
  frmMain: TfrmMain;
  hDIO: THandle;
  cParam: WDTPARAM;
  nReturn: DWORD;

implementation

{$R *.DFM}

procedure TfrmMain.Button1Click(Sender: TObject);
begin
     hDIO := CreateFile(WDT_DEVICE, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR
                    FILE_SHARE_WRITE, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL OR
                    FILE_FLAG_NO_BUFFERING, 0);

     if (hDIO > 0) then
     begin
          try
             cParam.data_b := Byte(StrToInt('$' + Edit1.Text));
          except
                cParam.data_b := Byte(StrToInt('$' + '0'));
          end;
          DeviceIoControl(hDIO, IOCTL_SYS_DIO_WRITE, @cParam, SizeOf(cParam), nil, 0, nReturn, nil);
          CloseHandle(hDIO);
     end
     else begin
          MessageDlg('Fehler, kein (gültiges) Handle!', mtWarning, [mbOK], 0);
     end;
end;

end.
Falls nochmal Fragen auftreten sollten, kann mir bestimmt wieder geholfen werden! Danke nochmal!

Robert Marquardt 11. Mai 2007 09:48

Re: IOCTL von C nach Delphi portieren
 
So ist es sauberer und einfacher.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TfrmMain = class(TForm)
    gboxWatchdog: TGroupBox;
    gboxIOOperations: TGroupBox;
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  public
  end;

type
  PWDTPARAM = ^WDTPARAM;
  WDTPARAM = record
    timeout: Byte;
    data_b: Byte;
  end;

const
     WDT_TYPE = $88B9; //35001;

     WDT_DEVICE  = '\\.\WDT_DEVICE';
     WDT_DEVICE_NAME = '\Device\WDT_DEVICE';
     WDT_DOS_DEVICE_NAME = '\DosDevices\WDT_DEVICE';

     IOCTL_SYS_WDT_SET_TIMEOUT = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($800 shl 2) or 0);
     IOCTL_SYS_WDT_START = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($801 shl 2) or 0);
     IOCTL_SYS_WDT_STOP  = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($802 shl 2) or 0);
     IOCTL_SYS_WDT_RESTART = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($803 shl 2) or 0);
     IOCTL_SYS_DIO_READ  = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($804 shl 2) or 0);
     IOCTL_SYS_DIO_WRITE = DWORD((WDT_TYPE shl 16) or (2 shl 14) or ($805 shl 2) or 0);

var
  frmMain: TfrmMain;

implementation

{$R *.DFM}

procedure TfrmMain.Button1Click(Sender: TObject);
var
  hDIO: THandle;
  cParam: WDTPARAM;
  nReturn: DWORD;
begin
     hDIO := CreateFile(WDT_DEVICE, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR
                    FILE_SHARE_WRITE, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL OR
                    FILE_FLAG_NO_BUFFERING, 0);

     if hDIO <> INVALID_HANDLE_VALUE then
     begin
          cParam.timeout := 0;
          cParam.data_b := Byte(StrToIntDef('$' + Edit1.Text, 0));
          DeviceIoControl(hDIO, IOCTL_SYS_DIO_WRITE, @cParam, SizeOf(cParam), nil, 0, nReturn, nil);
          CloseHandle(hDIO);
     end
     else begin
          MessageDlg('Fehler, kein (gültiges) Handle!', mtWarning, [mbOK], 0);
     end;
end;

end.
Lokale Variablen sind besser. Dazu muss dann aber das Element timeout explizit gesetzt werden. Bei globalen Variablen wird es implizit auf 0 gesetzt, aber bei lokalen Variablen ist der Inhalt Zufall.

NetSonic 11. Mai 2007 11:14

Re: IOCTL von C nach Delphi portieren
 
ok, du hast recht! so ist es einfach besser!
Hab mein "kleines" Programm zum Testen jetzt auch so weit zusammen, dass ich den integrierten Watchdog-Timer ansprechen kann. Übers Wochenende geht's dann an die Einbindung in das derzeitige Steuerungsprogramm.

Und da es schon Freitag-Mittag ist, wünsch ich Dir / allen anderen schon mal ein schönes Wochenende, mit halbwegs vernünftigem Wetter. Hier regnet es leider nur und wenn man schon so früh im Jahr mit so viel Sonne verwöhnt wird, nervt einen dieses Wetter echt ab!

MfG
NetSonic


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:45 Uhr.
Seite 2 von 2     12   

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