![]() |
IOCTL von C nach Delphi portieren
Ich habe folgenden C Quelltext vorliegen, den ich nach Delphi portieren möchte um die digitalen IO-Ports eines Industrie-Mainboards anzusprechen.
Code:
Wie muss die Umwandlung der IOCTL_SYS Funktionscodes aussehen? Diese müssen ja als CONST in Delphi definiert werden,
#define WDT_DEVICE "\\\\.\\WDT_DEVICE"
#define WDT_DEVICE_NAME L"\\Device\\WDT_DEVICE" #define WDT_DOS_DEVICE_NAME L"\\DosDevices\\WDT_DEVICE" // Device type #define WDT_TYPE 35001 // The IOCTL function codes from 0x800 to 0xFFF are for customer use. #define IOCTL_SYS_WDT_SET_TIMEOUT CTL_CODE(WDT_TYPE, 0x800, METHOD_BUFFERED, FILE_WRITE_ACCESS) #define IOCTL_SYS_WDT_START CTL_CODE(WDT_TYPE, 0x801, METHOD_BUFFERED, FILE_WRITE_ACCESS) #define IOCTL_SYS_WDT_STOP CTL_CODE(WDT_TYPE, 0x802, METHOD_BUFFERED, FILE_WRITE_ACCESS) #define IOCTL_SYS_WDT_RESTART CTL_CODE(WDT_TYPE, 0x803, METHOD_BUFFERED, FILE_WRITE_ACCESS) #define IOCTL_SYS_DIO_READ CTL_CODE(WDT_TYPE, 0x804, METHOD_BUFFERED, FILE_WRITE_ACCESS) #define IOCTL_SYS_DIO_WRITE CTL_CODE(WDT_TYPE, 0x805, METHOD_BUFFERED, FILE_WRITE_ACCESS) aber wir muss das aussehen? Vielleicht so...? Und wie rufe ich die dann auf?
Delphi-Quellcode:
Danke schonmal vorab, für eure Hilfe!
CONST
WDT_DEVICE = '\\.\WDT_DEVICE'; WDT_TYPE = $35001; IOCTL_SYS_DIO_WRITE = $805; |
Re: IOCTL von C nach Delphi portieren
WDT_TYPE = 35001;
Das ist eine Dezimalzahl. CTL_CODE ist ein Makro das ein DWORD per Bitschieben zusammensetzt. METHOD_BUFFERED und FILE_WRITE_ACCESS sind einfache Zahlenkonstanten. Es kommen also einfache Zahlen heraus. Ich bin jetzt gerade zu muede das alles nachzuschlagen und auszurechnen. |
Re: IOCTL von C nach Delphi portieren
Code:
Das entspricht folgendem Delphi-Code
#define CTL_CODE(DeviceType, Function, Method, Access) (
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) )
Delphi-Quellcode:
Da es in Delphi keine Makros gibt, kannst du den Ausdruck mit dem Taschenrechner ausrechnen und als Konstante
(DeviceType shl 16) or (Access shl 14) or (Function shl 2) or Method
hinschreiben oder du schreibst dir die Funktion CTL_CODE(DeviceType, Function, Method, Access:integer):integer und verwendest statt Konstanten eben Variablen. |
Re: IOCTL von C nach Delphi portieren
WDT_TYPE ist falsch - diese Zahl ist kein hexadezimaler Wert :warn:
CTL_CODE ist ja ein Makro, welches die Angaben zusammenrechnet, dieses kannst du auch selber machen und dann das ergebnis angeben (halt wo wie es bei dir schon aussieht). > Die Rechenformel und Konstanten findest du ja im PSDK. Zitat:
Es sind ja alles nur einfache Konstanten. |
Re: IOCTL von C nach Delphi portieren
Das heißt, es könnte dann so aussehen...
Delphi-Quellcode:
oder hab ich es jetzt voll nicht richtig verstanden?!?!
const
WDT_TYPE = 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 Form1: TForm1; DriveHandle: THandle; n: DWord; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); begin DriveHandle := 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 (DriveHandle > 0) then begin DeviceIoControl(DriveHandle, IOCTL_SYS_DIO_WRITE, NIL, sizeof('0xf'), NIL, 0, n, NIL); CloseHandle(DriveHandle); end else begin MessageDlg('Fehler, kein (gültiges) Handle!', mtWarning, [mbOK], 0); end; end; |
Re: IOCTL von C nach Delphi portieren
Die Konstante WDT_DEVICE auch verwenden. Dazu ist sie da.
Der DeviceIoControl Aufruf ist falsch. |
Re: IOCTL von C nach Delphi portieren
Ok, die Konstante hab ich jetzt eingepflegt und der Kompiler mosert und sagt mir:
"Konstantenausdruck verletzt untere grenzen" Steh ehrlich gesagt ein bissl auf'm Schlauch! Hat das mit dem fehlerhaften DeviceIOControl-Aufruf zu tun, den Du meinst? |
Re: IOCTL von C nach Delphi portieren
Das Problem ist das WDT_TYPE Integer und nicht Cardinal ist. Indem man es in eine Hex-Konstante umwandelt wird der Typ der Konstante implizit Cardinal statt Integer. Das sollte die Fehlermeldung erlegen.
Delphi-Quellcode:
Der DeviceIoControl-Aufruf macht ueberhaupt keinen Sinn. Es wird ein Puffer mit Laenge fuer die Eingabedaten und ein Puffer mit Laenge fuer die Ausgabedaten uebergeben. Je nach Aufruf kannn einer oder beide der Puffer nil sein. Das haengt davon ab welchen Befehl (hier IOCTL_SYS_DIO_WRITE) man angibt. Wo keine Daten rein- oder rausgehen da braucht man auch keinen Puffer. Die Angabe dafuer ist aber nil fuer den Pufferzeiger und 0 fuer die Pufferlaenge.
const
WDT_TYPE = $88B9; 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 Form1: TForm1; DriveHandle: THandle; n: DWORD; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); begin DriveHandle := CreateFile(WDT_DEVICE, GENERIC_READ orGENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_NO_BUFFERING, 0); if DriveHandle <> INVALID_HANLDE_VALUE then begin DeviceIoControl(DriveHandle, IOCTL_SYS_DIO_WRITE, nil, sizeof('0xf'), nil, 0, n, nil); CloseHandle(DriveHandle); end else MessageDlg('Fehler, kein (gültiges) Handle!', mtWarning, [mbOK], 0); end; "nil, sizeof('0xf')" ist aber eine unsinnige Angabe. Es soll etwas geschrieben werden (der Namensbestandteil _WRITE signalisiert das ueberdeutlich), aber es wird kein Puffer angegeben. "sizeof('0xf')" ist ein ebenso unsinniger Ausdruck. Soll das die Laenge des Strings '0xf' sein oder die Groesse eines Pointers? Gib doch mal den originalen C-Aufruf an. |
Re: IOCTL von C nach Delphi portieren
Ok, hier nachfolgend der originale c-aufruf
Code:
Ich danke Dir schon mal für die Mühe, die Du Dir machst mir zu Helfen...
DWORD nReturn;
WDTPARAM cParam; typedef struct tagWDTPARAM { unsigned char timeout; unsigned char data_b; } WDTPARAM, *PWDTPARAM; void CDigitalIODlg::Onwrite() { CHAR pbufio[256]; UCHAR data_b; // TODO: Add your control notification handler code here m_edit1.GetWindowText(pbufio, sizeof(pbufio)); // MessageBox(pbufio,MB_OK); sscanf(pbufio, "%2x", &data_b); ; cParam.data_b = data_b; DeviceIoControl(((CDigitalIOApp*)AfxGetApp())->m_hDIO, IOCTL_SYS_DIO_WRITE, &cParam, sizeof(WDTPARAM), NULL, 0, &nReturn, NULL); // printf("Digital IO Write Successfully. \n"); // } |
Re: IOCTL von C nach Delphi portieren
Wie du davon auf so einen Murks kommst ist mir unverstandlich.
sscanf parst einen String in dem ("%2x") ein Byte als zwei Hexziffern steht. Offensichtlich eine Eingabe des Users, denn der Text wird aus einem Editfeld geholt.
Delphi-Quellcode:
Das habe ich hier mal reingehackt.
type
PWDTPARAM = ^WDTPARAM; WDTPARAM = record timeout: Byte; data_b: Byte; end; var cParam: WDTPARAM; nReturn: DWORD; procedure TForm1.FormWrite(Sender: TObject) begin cParam.data_b := IntToStr('$' + Edit1.Text); DeviceIoControl(hDIO, IOCTL_SYS_DIO_WRITE, @cParam, SizeOf(cParam), nil, 0, nReturn, NULL); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:55 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