Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi How to TValue / TOmniValue (https://www.delphipraxis.net/178263-how-tvalue-tomnivalue.html)

haentschman 28. Dez 2013 08:33


How to TValue / TOmniValue
 
Guten Morgen alle... :hi:

Ich habe mich mal intensiv mit der Omni TL beschäftigt. Dazu habe ich sowohl das Handbuch als auch die Beispiele von den Delphi Tagen im Gebrauch.

Nun heißt es ja überall:
Zitat:

In short, TOmniValue is a smart record (record with functions and operators) which functions similar to a Variant or TValue but is faster. It can store simple data types, objects, interfaces and (in Delphi 2009 and newer) records.
...nun versuche ich der Funktion
Delphi-Quellcode:
CreateWorkItem(Value: TOmniValue)
des BackgrounndWorkers ein TObject(Instanz)zu übergeben. Egal wie ich es anstelle(direkt, extra TOmniValue, gecasted etc.), alle Versuche laufen in Fehler:
Zitat:

[DCC Fataler Fehler] backgroundWorker1.pas(119): F2084 Interner Fehler: URW1136
Zitat:

[DCC Fataler Fehler] BackgroundWorker.dpr(16): F2084 Interner Fehler: O780
Im Großen und Ganzen läuft es darauf hinaus, daß ich zu dämlich bin TOmniValue zu benutzen... :oops:

Die Suche nach einem "How to" brachte nix weltbewegendes zum Vorschein... :roll:

Ich bitte Euch hiermit um Erleuchtung. :wink:


Eine mögliche Lösung:
Delphi-Quellcode:
TTest = class
  strict private
    FDBMS: Integer;
  public
    property DBMS: Integer read FDBMS write FDBMS;
  end;
.
.
.
FTest: TTest; // Instanz ist erzeugt
.
.
.
FBkGet := Parallel.BackgroundWorker;
FBkGet.NumTasks(Environment.Process.Affinity.Count * 2);
FBkGet.OnRequestDone(
  procedure(const Sender: IOmniBackgroundWorker;
    const workItem: IOmniWorkItem)
  begin
      MarkLoaded(TTest(TOmniValue(workItem.Data).AsObject).DBMS); // Cast Orgie zurück
    end);
FBkGet.Execute(RetrievePageBk);

FBkGet.Schedule(FBkGet.CreateWorkItem(TOmniValue(FTest).AsObject)); // Cast Orgie um Objekt abzulegen
...funktioniert soweit. Nur ist mir die Cast Orgie zuwieder :roll:. Geht das besser?

Elvis 28. Dez 2013 10:03

AW: How to TValue / TOmniValue
 
Wenn du einen internal error kriegst, hast du wohl alles richtig gemacht.
Delphi hat's nur nicht kapiert.

haentschman 28. Dez 2013 10:26

AW: How to TValue / TOmniValue
 
Danke Elvis...
Ich habe inzwischen oben editiert. Ohne casten geht es wahrscheinlich nicht. Nur ein Integer wird bei CreateWorkItem() als Parameter ohne casten genommen. Alles Andere resultiert in o.g. Fehlern.

:hi:

himitsu 28. Dez 2013 13:57

AW: How to TValue / TOmniValue
 
Jupp, die "Internal Errors" sind ja "Bugs" im Compiler, der da irgendwo ein Problem hat.

- Da kannst du nur selber "schnell" versuchen irgendwas "Schwindliches" anzustellen.
- Oder du wendest dich an Embarcadero und bisstest darum, daß der Bug entfernt wird. (das kannst du inzwischen wohl praktisch vergessen)
- Oder du wendest die an die Omni-Läute, ob die als Unterstützung für dein altes Delphi, versuchen irgendwas an ihrem Projekt umzubauen, so daß es nicht mehr in diesen Bug reinläuft.

haentschman 28. Dez 2013 14:05

AW: How to TValue / TOmniValue
 
Hmmm... :roll:
...dann bin ich ja nicht der doofe? :cheer: (Kommt selten genug vor)

Meinst du so etwas? Auch ein Record in Verbindung mit TValue http://qc.embarcadero.com/wc/qcmain.aspx?d=93738
Zitat:

Unterstützung für dein altes Delphi
...grenzt bei XE schon fast an Beleidigung.

himitsu 28. Dez 2013 14:17

AW: How to TValue / TOmniValue
 
Das Erste kommt dem Nahe, was du eigentlich versuchen wolltest, also via Implicit-Operator, nur über eine "eigene" Variable.
Und das Letzte wäre ein explititer Cast, welchen ich eigentlich empfehlen würde.
Delphi-Quellcode:
// externer impliziter Cast über zusätzliche Variable
MyOmniValue := FTest; // MyOmniValue := TObject(FTest); so sähe die externe Variante des letzten Tipps aus (siehe nächsten Code-Block)
FBkGet.Schedule(FBkGet.CreateWorkItem(MyOmniValue));

// externe explizite Zuweisung über zusätzliche Variable
MyOmniValue.AsObject := FTest;
FBkGet.Schedule(FBkGet.CreateWorkItem(MyOmniValue));

// externer expliziter Cast über zusätzliche Variable
MyOmniValue := TOmniValue.CastFrom<TTest>(FTest);
FBkGet.Schedule(FBkGet.CreateWorkItem(MyOmniValue));

// interner expliziter Cast über automatisch generierte lokale Variable
FBkGet.Schedule(FBkGet.CreateWorkItem(TOmniValue.CastFrom<TTest>(FTest)));

Dein Rumgecaste sieht eher so bissl "sinnlos" aus.
TTest >= expliziter Cast über den TObject-Implicit-Operator => TOmniValue => aulesen über AsObject
=> TObject => automatischer impliziter Case über den selben Implicit-Operator => TOmniValue => TOmniValue => übergabe als Parameter

Wenn Letzteres geht, dann hätte ich es eher nochmal so versucht, damit der Compiler direkt mit dem TObject arbeitet und man die erste Zeile des vorhin genannten Casts auslässt:
Delphi-Quellcode:
FBkGet.Schedule(FBkGet.CreateWorkItem(TObject(FTest)));



[Edit] Oh, es ist schon gefixt.
Nja, selbst wenn du es selber gemeldet hättest, dann wäre es bestimmt sowieso nicht als Hotfix/Update für ältere Delphis gekommen.
"Kaufen sie doch was Neues" ist einfach zu nett.

haentschman 28. Dez 2013 15:45

AW: How to TValue / TOmniValue
 
Danke...
das sind ja quasi nur verschiedene "Schreibweisen" um den Compiler zu verwirren :-D Die meisten davon hatte ich schon durch...

Hier noch mal eine Zusammenfassung:
Delphi-Quellcode:
Test:= 'Test';
FBkGet.Schedule(FBkGet.CreateWorkItem(Test));
-> Fehler: O780
Delphi-Quellcode:
FBkGet.Schedule(FBkGet.CreateWorkItem('Test'));
-> Compiliert
Delphi-Quellcode:
FBkGet.Schedule(FBkGet.CreateWorkItem(FTest));
-> Fehler: O780
Delphi-Quellcode:
FBkGet.Schedule(FBkGet.CreateWorkItem(TObject(FTest)));
-> Compiliert
Delphi-Quellcode:
FBkGet.Schedule(FBkGet.CreateWorkItem(TOmniValue.CastFrom<TTest>(FTest)));
-> Compiliert
Delphi-Quellcode:
MyOmniValue := TOmniValue.CastFrom<TTest>(FTest);
FBkGet.Schedule(FBkGet.CreateWorkItem(MyOmniValue));
-> Compiliert
Delphi-Quellcode:
MyOmniValue.AsObject := FTest;
FBkGet.Schedule(FBkGet.CreateWorkItem(MyOmniValue));
-> Compiliert
Delphi-Quellcode:
MyOmniValue:= FTest;
FBkGet.Schedule(FBkGet.CreateWorkItem(MyOmniValue));
-> Compiliert

:wall: und nun kommt der Hit: Ich habe wahrscheinlich zig Varianten schon probiert gehabt. Immer bekam ich O780.
http://www.delphipraxis.net/1111175-post300.html
Zitat:

Mich nervt der "F2084 Internal Error: O780", der erst weggeht, wenn man Delphi neustartet
:wall: Super! Wieder einen Haufen Zeit versenkt.

Danke an Alle.

himitsu 28. Dez 2013 15:50

AW: How to TValue / TOmniValue
 
Zitat:

Zitat von haentschman (Beitrag 1241295)
[DELPHI]
Delphi-Quellcode:
FBkGet.Schedule(FBkGet.CreateWorkItem(TObject(FTest)));
-> Compiliert

Irgendwie hat da der Compiler ein Problemchen mit der Klassen-Vererbung
und kratzt ab, wo er TTest als TObjekt verwenden will.

Mein schöner Thread ... wollte da vor 'ner Weile reinschreiben, aber der wurde ja leider geschlossen. :cry:

haentschman 28. Dez 2013 16:01

AW: How to TValue / TOmniValue
 
Das mit der String Übergabe ist auch witzig... :roll:

Viel schlimmer finde ich aber den IDE Neustart. Wenn das nicht gewesen wäre, bzw. was ich nicht gemacht hatte, wäre ich früher auf eine Lösung gekommen. Dann hätte es aber diese Wissenssammlung nicht gegeben.


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