Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Compiler Fehler E2134 -> Type X has no Type Info


sky21 - Mo 03.08.09 12:49
Titel: Compiler Fehler E2134 -> Type X has no Type Info
Hi all

Ich habe einen Aufzählungstyp, welcher teilweise eigene Integerwerte (siehe unten, z.B. tmrc_error = 100) definitiert. Leider reklamiert aufgrund dessen mein Compiler, dass diese Art der Auzählung nicht möglich ist: E2134 Type 'TMyReturnCode' has no type info

Das ist insofern Schade, weil ich die definierten Codes als Strings ausgeben möchte. Wie würde ein eleganter Workaround aussehen?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
type
  TMyReturnCode = (
    tmrc_none,
    tmrc_ok
    tmrc_error = 100// TypInfo geht nicht mehr wegen dieser Zuweisung...
    tmrc_bla
  );


Ein äquivalentes Set von Codes im Stringformat ist keine gute Lösung (Man beachte, dass die Enum unendlich gross ist, hehe). Die Neuwertzuweisung muss ebenfalls beibehalten werden.



Delphi-Quelltext
1:
str := GetEnumName( TypeInfo(TMyReturnCode), Integer(Code)); // niet! Compiler Error E2134                    


BenBE - Mo 03.08.09 13:07

Delphi generiert nicht für alle Typen, die man deklarieren kann eine Typ-Info. Gerade für Records und Arrays gibt es generell keine (offiziell abrufbare*).

Warum er bei Enums mit definierten Konstanten jetzt keine RTTI erzeugt, müsste ich mir anschauen, könnte aber mit der Struktur der RTTI zusammenhängen, die IIRC für die Einzelelemente keinen Wert speichert. Somit ließe sich dieser Typ in der RTTI nur schwer darstellen.

*intern verwendet Delphi für Arrays bei Aufrufen der RTL Strukturen, die für ein Array die nötigen Daten liefern. Diese sind jedoch nicht via Typeinfo abrufbar.


sky21 - Mo 03.08.09 13:11

Danke für die Info. Da nichts von einem elegantem workaround geschrieben wurde, denke ich, dass es demnach keine solche Möglichkeit gibt oder? Muss demnach tatächlich ein Set von korrespondierenden Strings aufgebaut werden? Das riecht nach mächtig Fleissarbeit... für mich!


Tilman - Mo 03.08.09 13:17

Kannst du die Wertzuweiseung =100 nicht weglassen, und stattdessen sozusagen im letzten Moment konvertieren? also dass tmrc_error erst im letzten Moment 100 wird, also unmittelbar vor speichern / DLL aufruf / API-Aufruf oder warum auch immer es unbedingt 100 bei dir sein muss?


BenBE - Mo 03.08.09 13:19

Du kannst Dir die Typinfo für deinen Typ zur Not "von Hand" bauen und dort übergeben.

Eine weitere Möglichkeit besteht darin ein Mapping-Array (array[TDeinTyp] of String = ('var1''var2', ...);) bauen.

Elegant ist aber wirklich was anderes.

Das interessante an dem Thema ist ja eigentlich was anderes: Borland bietet seit jeher die nötigen Strukturen an, um selbst für Arrays und Records RTTI bereitzustellen; sogar für Pointer ließe sich das ohne große Probleme realisieren (Pointer = tkPointer mit Referenz auf verwiesenen Datentyp, für Typeinfo(Pointer) entsprechend ein tkPointer mit Referenz auf ein tkUnknown - wie gesagt alles vorhanden, außer tkPointer ;-)). Warum Borland das nicht macht, ist mir schleierhaft; zumal man das für .NET ja eh braucht (mehr oder weniger).

Ach ja, ein letzter Ansatz: Deklariere deinen Typ ohne die Zuweisung und ein weiteres Mal mit. Schreib Dir dann zwei Übersetzungsarrays nach oben genanntem Index-Schema.


sky21 - Mo 03.08.09 13:23

user profile iconTilman hat folgendes geschrieben Zum zitierten Posting springen:
Kannst du die Wertzuweiseung =100 nicht weglassen, und stattdessen sozusagen im letzten Moment konvertieren? also dass tmrc_error erst im letzten Moment 100 wird, also unmittelbar vor speichern / DLL aufruf / API-Aufruf oder warum auch immer es unbedingt 100 bei dir sein muss?


Ja diese ginge theoretisch, ist allerdings aber wieder mit Fleiss-/konvertierungsarbeit verbunden. Dann kann ich gleich eine passende Stringstruktur aufbauen. Das Problem ist eben schon wie von dir vermutet, dass die Codes von einer DLL Funktion (3rd party noch dazu) geworfen werden.

Naja, ich denke ich werde mich jetzt erstmals auf die wesentlichen Codes beschränken und die Restlicnen nach und nach bei Bedarf hinzufügen. Auf alle Fälle gebe ich noch zusätzlich den Integerwert aus, damit ich notfalls den Returncode im Quellcode/EnumType nachschlagen kann.

Danke für die Antworten ...
Solle es jedoch trotzdem irgendwie möglich sein, die Problematik elegant zu lösen, dann bitte, meldet euch ;-)