Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi ReadFileEx/WriteFileEx verwenden: Fehler in Windows.pas? (https://www.delphipraxis.net/107816-readfileex-writefileex-verwenden-fehler-windows-pas.html)

EConvertError 2. Feb 2008 17:16


ReadFileEx/WriteFileEx verwenden: Fehler in Windows.pas?
 
Hallo!

Beim Versuch dieses Beispiel in eine Delphi-Komponente zu packen, stoße ich schon wieder auf ein Problem.

Ich brauche diese beiden Funktionen (aus dem MSDN kopiert):
Code:
BOOL WINAPI WriteFileEx(
  __in     HANDLE hFile,
  __in_opt LPCVOID lpBuffer,
  __in     DWORD nNumberOfBytesToWrite,
  __inout  LPOVERLAPPED lpOverlapped,
  __in_opt LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
Code:
BOOL WINAPI ReadFileEx(
  __in      HANDLE hFile,
  __out_opt LPVOID lpBuffer,
  __in      DWORD nNumberOfBytesToRead,
  __inout   LPOVERLAPPED lpOverlapped,
  __in_opt  LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
Delphi-Quellcode:
type
  // TODO: Use classes here in the future (if possible)
  PPipeInstance = ^TPipeInstance;
  TPipeInstance = record
    Overlapped: TOverlapped;
    PipeHandle: THandle;
    chRequest: array[1..BUFSIZE] of Char;
    cbRead: DWord;
    chReply: array[1..BUFSIZE] of Char;
    cbToWrite: DWord;
  end;
...
var
  PPipeInst: PPipeInstance;
  AWrite: Boolean;
...
WriteFileEx(PPipeInst^.PipeHandle, @PPipeInst^.chReply[1], PPipeInst^.cbToWrite, POverlapped(PPipeInst), CompletedWriteMethod);
POverlapped(PPipeInst) schluckt er nicht, weil Delphi ein TOverlapped (_OVERLAPPED) verlangt:
Zitat:

[Pascal Fehler] NamedPipeServer.pas(70): E2010 Inkompatible Typen: '_OVERLAPPED' und 'POverlapped'
MSDN sagt aber eindeutig:
Zitat:

A pointer to an OVERLAPPED data structure...
Jetzt vermute ich einen Fehler in der Windows.pas, weshalb ich dort auch schon TOverlapped in POverlapped geändert habe. Nur schluckt er meinen Code noch immer nicht...
Wo muss man das ändern und ist das auch wirklich ein Fehler in Delphi?

Danke,
Andreas

PS: Bei ReadFileEx() verlangt Delphi wie erwartet ein POverlapped.

Christian Seehase 2. Feb 2008 17:24

Re: ReadFileEx/WriteFileEx verwenden: Fehler in Windows.pas?
 
Moin Andreas,

Zitat:

Zitat von EConvertError
Jetzt vermute ich einen Fehler in der Windows.pas, weshalb ich dort auch schon TOverlapped in POverlapped geändert habe.

hast Du die Windows.pas auch neu compiliert? (und vor allem: Vor der Änderung gesichert?)
Wenn nicht, wird immer die alte Unit verwendet.

Also in den Fällen, in denen ich mit mitgelieferten Deklarationen nicht klarkomme, importiere ich mir die Funktionen lieber selbst (statt in den VCL-Sourcen zu ändern)
Das macht dann auch die eventuelle Weitergabe von Sourcen einfacher, da jemand anderes dann nicht auf geänderte Originaldateien angewiesen ist (was jemand, der z.B., eine PE hat auch gar nicht machen könnte.)

Dezipaitor 2. Feb 2008 18:17

Re: ReadFileEx/WriteFileEx verwenden: Fehler in Windows.pas?
 
Du übergibst doch eindeutig deine eigene Struktur PPipeInst, wo POVERLAPPED verlangt ist.

Ich vermute, dass du eigentlich folgendes nutzen wolltest:

Delphi-Quellcode:
WriteFileEx(PPipeInst^.PipeHandle, @PPipeInst^.chReply[1], PPipeInst^.cbToWrite, PPipeInst.Overlapped, CompletedWriteMethod);
Edit:
Habe mir die Funktion angeschaut. Es müsste eigentlich ein Pointer auf OVERLAPPED sein.
Die JEDI-API exportiert es korrekt. Sogar in D2007 ist ein ein CONST.

Ich persönlich ziehe die JEDI Implementation vor.

EConvertError 2. Feb 2008 18:45

Re: ReadFileEx/WriteFileEx verwenden: Fehler in Windows.pas?
 
Zitat:

hast Du die Windows.pas auch neu compiliert? (und vor allem: Vor der Änderung gesichert?)
Wie kompiliert man die neu? DCU-Löschen hat es nicht getan....

Klar, habe ich vor den Änderungen gesichert. ;-) Wobei das ist nicht mehr so wichtig, weil ich mir die Funktionen auch noch mal selbst eingebunden habe. So gesehen bräuchte ich auch die JEDI-Header nicht mehr...

Zitat:

Du übergibst doch eindeutig deine eigene Struktur PPipeInst, wo POVERLAPPED verlangt ist.
Jupp, ist auch volle Absicht. ;-) Ein PPipeInstance kann man auf POverlapped casten, während man ein POverlapped nicht auf ein TOverlapped casten kann. In der MSDN-Vorlage (siehe Link oben) wird das auch gemacht. Wenn man das MSDN-Beispiel kompiliert funktioniert die Geschichte zumindest. Mal sehen ob ich das auch hinbekomme. :gruebel:

Anscheinend braucht man gar kein gültiges TOverlapped-Record, was bedeutet, dass ich auch einen Pointer auf ein Objekt (mein zukünftiges threadsicheres TNamedPipeClient) übergeben könnte. Das wollte ich mit dem Kommentar "Use classes here in the future" andeuten.

Mal sehen, ob sich meine Speicherzugriffsverletzung in Luft auflöst, oder ob es da noch ein Problem gibt...

Danke,
Andreas

PS: D2007 importiert es richtig? D.h. ich könnte da ein IFDEF einbauen?

DGL-luke 2. Feb 2008 19:12

Re: ReadFileEx/WriteFileEx verwenden: Fehler in Windows.pas?
 
ja, bei D2006 ist es ein const, d.h. ein impliziter pointer. da kannst du aber wieder keinen eigenen Pointer übergeben.

Dezipaitor 2. Feb 2008 19:32

Re: ReadFileEx/WriteFileEx verwenden: Fehler in Windows.pas?
 
Es kann kein CONST sein. Es ist laut Definition ein In/Out Wert, was entweder ein Pointer sein muss oder VAR.

---

Sorry, das Beispiel habe ich übersehen.
Aber darf ich fragen, ob du es verstanden hast? Das Beispiel ist doch sehr typisch für C und damit imho trickreich.

EConvertError 2. Feb 2008 19:56

Re: ReadFileEx/WriteFileEx verwenden: Fehler in Windows.pas?
 
Ja, doch so im Großen und Ganzen verstehe ich doch sehr gut, was die da tun.

Ich bekomme schon die Anfrage des Clients richtig rein. Die Antwort funktioniert noch nicht ganz (bekomme immer '?????' statt 'This is a test reply!'). Die Lösung wird wohl in der Verwendung der richtigen String-Sorte sein...

Die Callbacks funktionieren auch ganz gut, dank des MakeProcInstance-Tricks... ;-)

Andreas

DGL-luke 2. Feb 2008 19:57

Re: ReadFileEx/WriteFileEx verwenden: Fehler in Windows.pas?
 
bei D2006 IST es ein const. (upsa, ich hab ja gar kein D2007)

PS: const bedeutet pass-by-reference, genauso wie var und out. und es gibt bei diesen drei schlüsselwörtern in delphi keinen unterschied außer der sie repräsentierenden zeichenfolge.
EDIT: Und der Compiler weigert sich, die neuzuweisung eines const-params zu übersetzen. naja.

EConvertError 2. Feb 2008 20:04

Re: ReadFileEx/WriteFileEx verwenden: Fehler in Windows.pas?
 
Ja, Delphi 2006 (Turbo Edition) verwende ich auch. ;-)

Mir ist schon klar, was const bedeutet. Aber ich brauche es als Pointer, um diesen C-Trick nachmachen zu können. ;-) Und POverlapped ist sicher "korrekter" (weil sinngemäßer) übersetzt.

Ja, wie gesagt mein letztes Problem ist nur mehr, dass ich die Anfrage in ein Array of Char einlese. Da bekomme ich 't',#0,'e',#0,'s',#0,'#0','t',#0 (Der Rest des Buffers natürlich mit #0 gefüllt.). Zurückgesendet wird zurzeit ohne #0 dazwischen, was dann natürlich nicht gut funktioniert ('?????').

Der Client ist (zur Zeit noch!) nicht von mir... ;-)
Sonst könnte ich es ja auch anders einlesen.

Grüße,
Andreas

DGL-luke 2. Feb 2008 20:09

Re: ReadFileEx/WriteFileEx verwenden: Fehler in Windows.pas?
 
das ist dann wohl unicode...


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:59 Uhr.
Seite 1 von 2  1 2      

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