Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   FreePascal (https://www.delphipraxis.net/74-freepascal/)
-   -   Object anhand des Classennamens erstellen (https://www.delphipraxis.net/189362-object-anhand-des-classennamens-erstellen.html)

SirTwist 5. Jun 2016 12:48

Object anhand des Classennamens erstellen
 
Hallo Leute,

ich versuche seit kurzer Zeit, mich in Freepascal / Lazarus einzuarbeiten und meine (im Laufe von 15 Jahren gewachsene) Hilfsbibliotheken von Delphi umzubauen.

An einer Stelle möchte ich ein Objekt erstellen, dessen Klassennamen ich als String vorliegen habe (u.a. beim Einlesen einer XML-Datei). In Delphi habe ich das mit RTTI gelöst:
Delphi-Quellcode:
        rtti_context := TRttiContext.Create;
        rtti_instanceType := FindType(obj_classname);
        if not Assigned(rtti_instanceType) then exit;      
        create_method := rtti_instanceType.GetMethod('Create');
        if Assigned(create_method) then begin
          create_result := create_method.Invoke(rtti_instanceType.MetaclassType, []);
          aObj := create_result.AsObject;
        end else begin
          aObj := rtti_instanceType.MetaclassType.Create;
        end;
(bereinigt um Kommentare, Fehlermeldungen etc...)

Das scheint mir im aktuelle Freepascal (3.0.0, 51630) offensichtlich nicht zur Verfügung. Also habe ich gegoogelt, und diese Lösung gefunden:
Delphi-Quellcode:
    class_type := GetClass(obj_classname);
    aObj := class_type.Create;
Das erzeugt mir zwar ein Objekt, ruft aber nicht den klassenspezifischen Constructor auf. Außerdem funktioniert es nur mit Klassentypen, die ich vorher explizit registriert habe, und die von TPersistent abgeleitet sind. Das Objekt hat aber den richtigen Typ, ein Aufruf von aObj.Classname ergibt das, was vorher in obj_classname stand.

Übersehe ich irgendeine fluffige Möglichkeit, aus einem Klassennamen als String das passende Objekt zu erzeugen?


Vielen Dank für eure Hilfe!

Schöne Grüße,
Michael

Lee6 19. Sep 2020 11:24

AW: Object anhand des Classennamens erstellen
 
Um ein Objekt von MyClass zu erstellen, geben Sie den Klassennamen gefolgt vom Objektnamen an und verwenden Sie das Schlüsselwort new: Example. Erstellen Sie ein Objekt mit dem Namen "myObj" und drucken Sie den Wert von x: public class MyClass {int x = 5; public static void main (String [] args) {MyClass myObj = new MyClass (); System. Beispiel. OtherClass.

SirTwist 19. Sep 2020 11:31

AW: Object anhand des Classennamens erstellen
 
Hallo Lee,

du bist hier in einem Delphi-Forum. Herzlich Willkommen! Lies dich doch bitte erstmal ein paar Tage ein und werde mit der neuen Sprache vertraut. Nach und nach findest Du dann bestimmt auch die Möglichkeit, bei Beiträgen hilfreiche Antworten zu finden.

Zitat:

Zitat von Lee6 (Beitrag 1473862)
Um ein Objekt von MyClass zu erstellen, geben Sie den Klassennamen gefolgt vom Objektnamen an und verwenden Sie das Schlüsselwort new: Example. Erstellen Sie ein Objekt mit dem Namen "myObj" und drucken Sie den Wert von x: public class MyClass {int x = 5; public static void main (String [] args) {MyClass myObj = new MyClass (); System. Beispiel. OtherClass.

Deine Antwort geht leider völlig an meiner Frage vorbei. Du beschreibst hier Grundlagen von C++, nicht von Delphi/Freepascal. Und ich habe danach gefragt, wie man ein Objekt anlegen kann, dessen Klassennamen in einer Stringvariablen steht.

Schöne Grüße,
Sir Twist

Uwe Raabe 19. Sep 2020 11:43

AW: Object anhand des Classennamens erstellen
 
Ich fürchte, deine Ausführungen gehen ins Leere. Die Antwort von Lee6 ist im Wesentlichen eine automatische Übersetzung eines Teils dieser Seite: https://www.w3schools.com/java/java_classes.asp und stinkt ganz gewaltig nach Bot.

Zitat:

To create an object of MyClass, specify the class name, followed by the object name, and use the keyword new:

Example
Create an object called "myObj" and print the value of x:

public class MyClass {
int x = 5;

public static void main(String[] args) {
MyClass myObj = new MyClass();
System.out.println(myObj.x);
}
}

venice2 19. Sep 2020 12:41

AW: Object anhand des Classennamens erstellen
 
Hier sind seit ein paar Tagen irgendwelche Spinner unterwegs. Sorry muss das leider so krass ausdrücken.
Siehe.
@aris0514 und seine Antworten. (Kommentare)

Aber vielleicht soll das so sein. :)

EDIT:
Sehe gerade du hast ja schon etwas dazu geschrieben. Sorry post war unnötig.

himitsu 19. Sep 2020 14:13

AW: Object anhand des Classennamens erstellen
 
OK, den Spämmer ignorieren wir einfach mal.

Ja, über die RTTI kannst du eine Klasse suchen.
Alternativ gibt es auch Delphi-Referenz durchsuchenRegisterClass und Delphi-Referenz durchsuchenFindClass.



Jene werden auch von der VCL und FMX benutzt.
Beim Create einer TForm, werden über die published Fields in der Form-Klasse die enthaltenen Komponenten-Typen registriert,
und während des Ladens sucht dann der DFM-Reader die namentlich in der DFM stehenden Klassen in dieser Liste.
PS: Drum knallt es auch, wenn man eine Komponente auf der Form hat, aber keine publisched Variable dieses Types in der Form existiert. (und dieser Typ vorher auch nicht registriert war)

Hat man Klassen in Sub-Typen, welche keine "Variable" in der Form-Klasse besitzen, dann muß man diese Klassen manuel registrieren.
z.B. bei einer Liste/Collection als Property in einer Komponente oder bei einer Komponente die aus weiteren Komponenten bestecht.

Delphi-Quellcode:
{ Class registration routines }

procedure RegisterClass(AClass: TPersistentClass);
procedure RegisterClasses(const AClasses: array of TPersistentClass);
procedure RegisterClassAlias(AClass: TPersistentClass; const Alias: string);
procedure UnRegisterClass(AClass: TPersistentClass);
procedure UnRegisterClasses(const AClasses: array of TPersistentClass);
procedure UnRegisterModuleClasses(Module: HMODULE);
function FindClass(const ClassName: string): TPersistentClass;
function GetClass(const AClassName: string): TPersistentClass;
procedure StartClassGroup(AClass: TPersistentClass);
procedure GroupDescendentsWith(AClass, AClassGroup: TPersistentClass);
function ActivateClassGroup(AClass: TPersistentClass): TPersistentClass;
function ActiveClassGroup: TPersistentClass;
function ClassGroupOf(AClass: TPersistentClass): TPersistentClass; overload;
function ClassGroupOf(Instance: TPersistent): TPersistentClass; overload;

procedure ReportClassGroups(Report: TStrings);

JamesTKirk 2. Nov 2020 15:17

AW: Object anhand des Classennamens erstellen
 
Zitat:

Zitat von SirTwist (Beitrag 1339552)
Übersehe ich irgendeine fluffige Möglichkeit, aus einem Klassennamen als String das passende Objekt zu erzeugen?

Nein, übersiehst du nicht. FPC hat einfach noch keine Unterstützung für die Extended RTTI von Delphi und auch wenn 3.2.0 mittlerweile die Rtti Unit hat, so fehlen der dennoch einige Funktionalitäten (eben vor allem die, welche auf die Extended RTTI aufsetzen).


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