Autor |
Beitrag |
Peter18
Beiträge: 489
Erhaltene Danke: 2
Delphi4
|
Verfasst: Fr 06.03.15 15:41
Ein freundliches Hallo an alle,
ich bin dabei einige Api-Definitionen an mein Delphi 4 anzupassen. Eine Lösung, die ich gefunden habe, benutzt entsprechende Dateien aus höheren Versionen. Dei der Anpassung bin ich auf folgendes Problem gestoßen:
In einer Klasse ist der Constructor überladen deklariert. Der erste Constructor geht auch ohne Fehlermeldung durch. Bei dem 2. behauptet er die Klassenbezeichnung nicht mehr zu kennen. Bei Delphi 4 ist es sonst so, dass Vorwärtsdeklarationen und Functionen oder Prozeduren jeweils mit "overload;" versehen werden müssen.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| TEvent = class(THandleObject) public constructor Create(EventAttributes: PSecurityAttributes; ManualReset, InitialState: Boolean; const Name: string; UseCOMWait: Boolean = False); overload; constructor Create(UseCOMWait: Boolean = False); overload;
constructor TEvent.Create(EventAttributes: PSecurityAttributes; ManualReset, InitialState: Boolean; const Name: string; UseCOMWait: Boolean); begin ... end;
constructor TEvent.Create(UseCOMWait: Boolean); begin ... end; |
Hier schluckt der Compiler "overload;" bei der Vorwärtsdeklarationen nicht aber wenn der Constructor definiert wird.
Meine Frage: Kann Delphi 4 das nicht oder muß da syntaktisch etwas anders gehandhabt werden oder kann man tricksen?
Grüße von der Nordsee
Peter
|
|
mandras
Beiträge: 430
Erhaltene Danke: 107
Win 10
Delphi 6 Prof, Delphi 10.4 Prof
|
Verfasst: Fr 06.03.15 19:49
Kannst Du dies bitte näher erläutern, welche Fehlermeldung in welcher Zeite usw.?
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 06.03.15 21:15
TEvent braucht man nicht wirklich. Die API-Befehle sind quasi 1:1 gleich vom Aufruf her.
Aber Delphi 4 kompiliert den geposteten Quelltext bei mir problemlos. Überladene Methoden waren da ja gerade neu.
|
|
Peter18
Beiträge: 489
Erhaltene Danke: 2
Delphi4
|
Verfasst: Sa 07.03.15 20:30
Hallo mandras,
mandras hat folgendes geschrieben : | Kannst Du dies bitte näher erläutern, welche Fehlermeldung ... |
Peter18 hat folgendes geschrieben : | Bei dem 2. behauptet er die Klassenbezeichnung nicht mehr zu kennen |
mandras hat folgendes geschrieben : | ... in welcher Zeite usw.? |
Peter18 hat folgendes geschrieben : | Bei dem 2. behauptet er die Klassenbezeichnung nicht mehr zu kennen |
Also Zeile 13.
Hallo jaenicke,
Dank für Deine Antwort! Ich habe es auch noch mal probiert und siehe da, geht durch. Aber warum muß "overload" in diesem Fall nur bei der Vorwärtsdeklaration stehen und sonst bei beiden?
Kurz zum Hintergrund: Ich habe die Datei "UDP-Socket-Utility für Delphi" gefunden und wollte mir ansehen was dort geschieht, weil ich bisher keine Beschreibung gefunden habe, mit der ich Client/Server selbst aufbauen könnte. Daher habe ich einfach in den Dateien von Turbo Delphi nach dem gesucht, was der Compiler anmeckert und in eine Include-Datei geschrieben, um Doppeldeklarationen zu vermeiden.
Ich habe nun die Include-Datei durchgesehen, ob dort Syntaxfehler drin sind, die der Compiler übersehen hat und dadurch später auf die Nase fällt. Negativ.
In der Datei "SyncObjs" kommt mir eine Function aber spanisch vor:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| function InternalCoWaitForMultipleHandles(dwFlags: DWORD; dwTimeOut: DWORD; cHandles: LongWord; var Handles; var lpdwIndex: DWORD): HRESULT; stdcall; var WaitResult : DWORD; OleThreadWnd: HWnd; Msg : TMsg; begin WaitResult := 0; OleThreadWnd := GetOleThreadWindow; if OleThreadWnd <> 0 then while True do begin WaitResult := MsgWaitForMultipleObjectsEx(cHandles, Handles, dwTimeOut, QS_ALLEVENTS, dwFlags); if WaitResult = WAIT_OBJECT_0 + cHandles then begin if PeekMessage(Msg, OleThreadWnd, 0, 0, PM_REMOVE) then begin TranslateMessage(Msg); DispatchMessage(Msg); end; end else Break; end else WaitResult := WaitForMultipleObjectsEx(cHandles, @Handles, dwFlags and COWAIT_WAITALL <> 0, dwTimeOut, dwFlags and COWAIT_ALERTABLE <> 0); if WaitResult = WAIT_TIMEOUT then Result := RPC_E_TIMEOUT else if WaitResult = WAIT_IO_COMPLETION then Result := RPC_S_CALLPENDING else begin Result := S_OK; if (WaitResult >= WAIT_ABANDONED_0) and (WaitResult < WAIT_ABANDONED_0 + cHandles) then lpdwIndex := WaitResult - WAIT_ABANDONED_0 else lpdwIndex := WaitResult - WAIT_OBJECT_0; end; end; |
Ich meine am Ende der Zeile 23 sollte ein ";" stehen und wenn ich das richtig sehe fehlt auch ein "End;" Sollte also so aussehen:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| function InternalCoWaitForMultipleHandles(dwFlags: DWORD; dwTimeOut: DWORD; cHandles: LongWord; var Handles; var lpdwIndex: DWORD): HRESULT; stdcall; var WaitResult : DWORD; OleThreadWnd: HWnd; Msg : TMsg; begin WaitResult := 0; OleThreadWnd := GetOleThreadWindow; if OleThreadWnd <> 0 then while True do begin WaitResult := MsgWaitForMultipleObjectsEx(cHandles, Handles, dwTimeOut, QS_ALLEVENTS, dwFlags); if WaitResult = WAIT_OBJECT_0 + cHandles then begin if PeekMessage(Msg, OleThreadWnd, 0, 0, PM_REMOVE) then begin TranslateMessage(Msg); DispatchMessage(Msg); end; end else Break; end; <=== else WaitResult := WaitForMultipleObjectsEx(cHandles, @Handles, dwFlags and COWAIT_WAITALL <> 0, dwTimeOut, dwFlags and COWAIT_ALERTABLE <> 0); if WaitResult = WAIT_TIMEOUT then Result := RPC_E_TIMEOUT else if WaitResult = WAIT_IO_COMPLETION then Result := RPC_S_CALLPENDING else begin Result := S_OK; if (WaitResult >= WAIT_ABANDONED_0) and (WaitResult < WAIT_ABANDONED_0 + cHandles) then lpdwIndex := WaitResult - WAIT_ABANDONED_0 else lpdwIndex := WaitResult - WAIT_OBJECT_0; end; <=== end; end; |
( Zeile 23 und 38 ) Oder ist hier getrixt worden um Schreibarbeit zu sparen?? Bevor ich eine Systemdatei ändere laß ich mich doch lieber beraten.
Grüße von der Nordsee
Peter
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 07.03.15 22:49
Peter18 hat folgendes geschrieben : | Aber warum muß "overload" in diesem Fall nur bei der Vorwärtsdeklaration stehen und sonst bei beiden? |
Ach jetzt verstehe ich. Du meinst unter interface und nicht unter implementation. Das ist immer so. Die Modifizierer werden unter implementation nicht wiederholt.
Vorwärtsdeklarationen sind etwas anderes. Das bedeutet, dass du einen Typ unter interface einmal einführst und dann später unter interface komplett deklarierst. Kurzes Beispiel: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TTest = class;
TTest1 = class a: TTest; end;
TTest = class b: TTest1; end; | Nicht dass das Beispiel schön wäre... diese Kreuzbeziehung ist natürlich schlecht.
Peter18 hat folgendes geschrieben : | Ich meine am Ende der Zeile 23 sollte ein ";" stehen und wenn ich das richtig sehe fehlt auch ein "End;" Sollte also so aussehen: |
Vor else darf kein Semikolon stehen. Der erste Quelltext ist vollkommen korrekt.
Deine Einrückung des else Abschnitts ist etwas abenteuerlich, das ist im Original sinnvoller.
Und die Zeile if WaitResult = WAIT_IO_COMPLETION then Result := RPC_S_CALLPENDING ist extrem schlechter Programmierstil, da mehrere Befehle in einer Zeile stehen (die if-Bedingung und die Zuweisung an Result).
Sprich der erste Quelltext ist korrekt und sauber formatiert, der zweite nicht.
Aber warum benutzt du nicht einfach Turbo Delphi statt von dort zu kopieren? Das kann mehr, hat eine deutlich bessere Oberfläche und hat schon die Funktionen, die du brauchst, ohne viel Aufwand betreiben zu müssen...
|
|
Peter18
Beiträge: 489
Erhaltene Danke: 2
Delphi4
|
Verfasst: So 08.03.15 11:41
Hallo jaenicke,
Dank für Deine Antwort. Doch etwas leuchtet mir noch nicht ein. Wo ist das zu "while True do" (Zeile 11) gehörende "End;"?
jaenicke hat folgendes geschrieben : | Ach jetzt verstehe ich. Du meinst unter interface und nicht unter implementation. Das ist immer so. Die Modifizierer werden unter implementation nicht wiederholt. |
Sorry das habe ich in einen Topf geworfen.
Dass ich Turbo Delphi nicht verwende liegt vor allem daran, dass die Hilfe nicht funktioniert und ich dafür noch keine Lösung gefunden habe. Daher kann ich nicht ausprobieren, ob die Programme dann auch auf älteren Rechnern und USB-Stiften funktionieren (Ohne installation).
Grüße von der Nordsee
Peter
|
|
WasWeißDennIch
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: So 08.03.15 11:51
Peter18 hat folgendes geschrieben : | Wo ist das zu "while True do" (Zeile 11) gehörende "End;"? |
Hinter dem Break. Und mit Turbo Delphi erstellte Programme sollten auch unter älteren OS laufen, wenn es nicht gerade Win9x ist.
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 08.03.15 11:56
Peter18 hat folgendes geschrieben : | Wo ist das zu "while True do" (Zeile 11) gehörende "End;"? |
Das ist schon das, das du mit dem Semikolon versehen hast, aber das ist vor dem else eben nicht zulässig. Ob das end dabei zu dem if vor dem else gehört, ist dabei irrelevant, es darf auch sonst kein Semikolon vor das else.
|
|
Peter18
Beiträge: 489
Erhaltene Danke: 2
Delphi4
|
Verfasst: Mo 09.03.15 12:05
Hallo jaenicke,
Nochmals Dank für Deine Antwort. Da ist ja der Kronleuchter! Endlich ist er mir augegangen. Ich habe übersehen, dass dort kein "Begin" steht. Wer lesen kann ist klar im Vorteil. (Deshalb schreibe ich bei längeren Konstrukten "begin"und "end" hin, auch wenn das nicht notwendig ist.)
Dann muß der Fehler wohl doch in der Include-Datei stecken.
In der Tat, dort waren die Fehler!
Grüße von der Nordsee
Peter
|
|
|