Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi unnamed TEvent verwenden? (https://www.delphipraxis.net/164990-unnamed-tevent-verwenden.html)

himitsu 9. Dez 2011 00:17

Delphi-Version: 2010

unnamed TEvent verwenden?
 
Laut dem MSDN sollte das ja nicht richtig funktionieren.

Nutzt jemand diese Klasse denn auch ohne Namen?

Delphi-Quellcode:
constructor TEvent.Create(EventAttributes: PSecurityAttributes; ManualReset,
  InitialState: Boolean; const Name: string; UseCOMWait: Boolean);
{$IFDEF MSWINDOWS}
begin
  inherited Create(UseCOMWait);
  FHandle := CreateEvent(EventAttributes, ManualReset, InitialState, PChar(Name));
end;
{$ENDIF}
Zitat:

Zitat von MSDN
If lpName is NULL, the event object is created without a name.

Das "Problem", welches ich grade seh, ist daß PChar(Name) niemals NULL/nil sein wird und somit müßte das dann doch ein Named-Event werden,
oder zählen hier, entgegen der Dokumentation, Leerstrings auch als "NULL"? :gruebel:


Nicht daß sich dann am Ende, unter blöden Umständen, mehrere verschiedene Events sich gegenseitig auslösen. :cry:
(falls nicht schon passende Antworten kommen, werde ich wohl am WE wieder mal Stunden mit "sinnlosen" Bugfix-Tests zubringen müssen, wobei ich nicht unbedingt jede Windows-Version testen kann)


Nein, an Emba bin ich noch nicht getreten, aber selbst wenn die ein Bugfix rausbringen, dann garantiert nicht für ältere Delphi-Versionen vor XE2.
Und da das für eine Komponente angedacht ist und da nicht jeder XE2 daheim rumliegen hat ...........

Bummi 9. Dez 2011 06:46

AW: unnamed TEvent verwenden?
 
Ich kann nur raten, aber im Windowsspeicher dürften wegen der 0-Terminierung bei NIL und '' jeweils #0 stehen.

flipdascript 9. Dez 2011 09:16

AW: unnamed TEvent verwenden?
 
Ich/Wir nutzen diese Klasse grundsätzlich nur ohne Namen. Ob Delphi nun aus PChar('') NULL macht oder ob Windows anders als in der Dokumentation auch einen Leerstring wie NULL behandelt weiß ich nicht. Ich weiß aber sicher das TEvent Objekte die mit '' als Name kreiiert werden sich gegenseitig nicht "auslösen".

Man kann auch ganz einfach testen ob die Events gemeinsam genutzt werden würden. Einfach eine Anwendung die ein unnamned TEvent erzeugt schreiben, und nach Erzeugung des Events GetLastError aufrufen und die Fehlermeldung anzeigen lassen (SysErrorMessage). Wenn man diese Anwendung nun zweimal startet wird man zweimal "Der Vorgang wurde erfolgreich beendet" sehen. Wenn man einen Namen vergibt so sieht man einmal "Der Vorgang wurde erfolgreich beendet", und in der zweiten gestarteten Anwendung "Eine Datei kann nicht erstellt werden, wenn sie bereits vorhanden ist".

himitsu 9. Dez 2011 14:10

AW: unnamed TEvent verwenden?
 
Zitat:

Zitat von Bummi (Beitrag 1140422)
Ich kann nur raten, aber im Windowsspeicher dürften wegen der 0-Terminierung bei NIL und '' jeweils #0 stehen.

Das ist eben das Ungewisse, denn für Windows bei PChar ist nil <> ''.

nil = Zeiger mit dem Wert nil
'' = Zeiger auf einen Spicherbereich, welcher direk mit einer #0 beginnt




OK, dann will ich flipdascript mal glauben.
Wenn's doch nicht geht dann weiß ich ja wer Schuld ist. :angle2:

Bummi 9. Dez 2011 14:36

AW: unnamed TEvent verwenden?
 
scheint mir irgendwie auf das gleiche raus zu kommen
Delphi-Quellcode:
var
 a:TObject;
 i:integer;
begin
  a := nil;
  Move(a,i,4);
  Showmessage(IntToStr(i));
 
  // oder einfach
 
  Showmessage(IntToStr(Integer(nil)));
end;

himitsu 9. Dez 2011 16:21

AW: unnamed TEvent verwenden?
 
ja klar, du hast jetzt aus dem i einen Pointer gemacht, bzw. ihn mit dessen Wert "nil"/0 gefüllt.
Das hat aber nichts mit dem zu tun, was "in" den Pointer ist, bzw. worauf der Zeigt.

Delphi-Quellcode:
var
  S: String;
  P1, P2: Pointer;

S := '';
P1 := PChar(S);
P2 := Pointer(S);

ShowMessage(Format('%p %p', [P1, P2]));

if PByte(P1)^ = 0 then ;
if PByte(P2)^ = 0 then ; // zugriffsverletzung

Bummi 9. Dez 2011 16:44

AW: unnamed TEvent verwenden?
 
es wird ja ein PChar übergeben der nicht vorhandene Inhalt als in eine interne 0-terminierte variable kopiert die dann imho nicht von einem Nil unterschieden werden kann.

ich verstehe das ganze so:
Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
var
  S: String;
  P1, P2, P3: Pointer;
  A,B,C:String;
begin
S := '';
P1 := PChar('');
P2 := Pointer(S);
P3 := nil;
A := PChar(P1);
B := PChar(P2);
C := PChar(P3);
Showmessage(IntToStr(Length(A)) + ' - ' +IntToStr(Length(B)) + ' - ' + IntToStr(Length(C)));
end;

himitsu 9. Dez 2011 19:47

AW: unnamed TEvent verwenden?
 
Ich dürft den Delphi-String nicht mit einem PChar gleichsetzen.

himitsu 9. Dez 2011 22:01

AW: unnamed TEvent verwenden?
 
Delphi-Quellcode:
uses
  SyncObjs;

var
  E, E2: TEvent;

E := TEvent.Create(nil, True, False, 'fdfcyxvcx123');
Memo1.Lines.Add(SysErrorMessage(GetLastError));
E2 := TEvent.Create(nil, True, False, 'fdfcyxvcx789');
Memo1.Lines.Add(SysErrorMessage(GetLastError));
if E2.WaitFor(100) = wrTimeout then
  Memo1.Lines.Add('Timeout: v1');
E.SetEvent;
if E2.WaitFor(100) = wrTimeout then
  Memo1.Lines.Add('Timeout: v2');
E2.SetEvent;
if E2.WaitFor(100) = wrTimeout then
  Memo1.Lines.Add('Timeout: v3');
E2.Free;
E.Free;

E := TEvent.Create(nil, True, False, 'fdfcyxvcx456');
Memo1.Lines.Add(SysErrorMessage(GetLastError));
E2 := TEvent.Create(nil, True, False, 'fdfcyxvcx456');
Memo1.Lines.Add(SysErrorMessage(GetLastError));
if E2.WaitFor(100) = wrTimeout then
  Memo1.Lines.Add('Timeout: g1');
E.SetEvent;
if E2.WaitFor(100) = wrTimeout then
  Memo1.Lines.Add('Timeout: g2');
E2.SetEvent;
if E2.WaitFor(100) = wrTimeout then
  Memo1.Lines.Add('Timeout: g3');
E2.Free;
E.Free;

E := TEvent.Create(nil, True, False, '');
Memo1.Lines.Add(SysErrorMessage(GetLastError));
E2 := TEvent.Create(nil, True, False, '');
Memo1.Lines.Add(SysErrorMessage(GetLastError));
if E2.WaitFor(100) = wrTimeout then
  Memo1.Lines.Add('Timeout: u1');
E.SetEvent;
if E2.WaitFor(100) = wrTimeout then
  Memo1.Lines.Add('Timeout: u2');
E2.SetEvent;
if E2.WaitFor(100) = wrTimeout then
  Memo1.Lines.Add('Timeout: u3');
E2.Free;
E.Free;
Jupp, sieht gut aus ... na dann bin ich mal beruhigt.

Danke nochmal für den Denkanstoß mit GetLastError. :thumb:
Irgendwie war ich hier garnicht auf die Idee gekommen, daß man einen Status als Fehlercode verstecken könnte. :oops:


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:16 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