AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi IOCTL von C nach Delphi portieren
Thema durchsuchen
Ansicht
Themen-Optionen

IOCTL von C nach Delphi portieren

Ein Thema von NetSonic · begonnen am 10. Mai 2007 · letzter Beitrag vom 11. Mai 2007
Antwort Antwort
Seite 1 von 2  1 2      
NetSonic

Registriert seit: 10. Mai 2007
124 Beiträge
 
Delphi 10 Seattle Professional
 
#1

IOCTL von C nach Delphi portieren

  Alt 10. Mai 2007, 16:18
Ich habe folgenden C Quelltext vorliegen, den ich nach Delphi portieren möchte um die digitalen IO-Ports eines Industrie-Mainboards anzusprechen.

Code:
#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)
Wie muss die Umwandlung der IOCTL_SYS Funktionscodes aussehen? Diese müssen ja als CONST in Delphi definiert werden,
aber wir muss das aussehen? Vielleicht so...? Und wie rufe ich die dann auf?

Delphi-Quellcode:
CONST
  WDT_DEVICE = '\\.\WDT_DEVICE';
  WDT_TYPE = $35001;
  IOCTL_SYS_DIO_WRITE = $805;
Danke schonmal vorab, für eure Hilfe!
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#2

Re: IOCTL von C nach Delphi portieren

  Alt 10. Mai 2007, 16:33
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.
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#3

Re: IOCTL von C nach Delphi portieren

  Alt 10. Mai 2007, 16:34
Code:
#define CTL_CODE(DeviceType, Function, Method, Access) (
  ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)
)
Das entspricht folgendem Delphi-Code
(DeviceType shl 16) or (Access shl 14) or (Function shl 2) or Method Da es in Delphi keine Makros gibt, kannst du den Ausdruck mit dem Taschenrechner ausrechnen und als Konstante
hinschreiben oder du schreibst dir die Funktion CTL_CODE(DeviceType, Function, Method, Access:integer):integer und
verwendest statt Konstanten eben Variablen.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

Re: IOCTL von C nach Delphi portieren

  Alt 10. Mai 2007, 16:36
WDT_TYPE ist falsch - diese Zahl ist kein hexadezimaler Wert

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 von NetSonic:
Und wie rufe ich die dann auf?
Wie meinst du das?
Es sind ja alles nur einfache Konstanten.
$2B or not $2B
  Mit Zitat antworten Zitat
NetSonic

Registriert seit: 10. Mai 2007
124 Beiträge
 
Delphi 10 Seattle Professional
 
#5

Re: IOCTL von C nach Delphi portieren

  Alt 10. Mai 2007, 16:43
Das heißt, es könnte dann so aussehen...

Delphi-Quellcode:
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;
oder hab ich es jetzt voll nicht richtig verstanden?!?!
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#6

Re: IOCTL von C nach Delphi portieren

  Alt 10. Mai 2007, 16:53
Die Konstante WDT_DEVICE auch verwenden. Dazu ist sie da.
Der DeviceIoControl Aufruf ist falsch.
  Mit Zitat antworten Zitat
NetSonic

Registriert seit: 10. Mai 2007
124 Beiträge
 
Delphi 10 Seattle Professional
 
#7

Re: IOCTL von C nach Delphi portieren

  Alt 10. Mai 2007, 16:58
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?
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#8

Re: IOCTL von C nach Delphi portieren

  Alt 11. Mai 2007, 08:16
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:
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;
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.
"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.
  Mit Zitat antworten Zitat
NetSonic

Registriert seit: 10. Mai 2007
124 Beiträge
 
Delphi 10 Seattle Professional
 
#9

Re: IOCTL von C nach Delphi portieren

  Alt 11. Mai 2007, 09:08
Ok, hier nachfolgend der originale c-aufruf

Code:
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");

//
}
Ich danke Dir schon mal für die Mühe, die Du Dir machst mir zu Helfen...
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#10

Re: IOCTL von C nach Delphi portieren

  Alt 11. Mai 2007, 09:29
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:
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;
Das habe ich hier mal reingehackt.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:40 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