Nicht TForm-Objekt aus BPL erzeugen
-
Hallo zusammen,
zum Erzeugen von Objekten deren Klassen in BPLs definiert sind, verwende ich folgenden Mechanismus:
THandle PackageHandle = LoadPackage("Package"); TClass UnitClass = GetClass("TForm1"); TForm1 *Form1; Application->CreateForm(UnitClass, &Form1);
Auf diese Art kann ich aber nur Instanzen von Klassen erzeugen, die von TForm
abgeleitet sind, will aber auch andere Klassen verwenden.Es müsste also eine Alternative für Application->CreateForm() her...
Leider komme ich an diesem Punkt nicht weiter und bin mir auch nicht ganz sicher ob das überhaupt möglich ist. Hoffe ihr könnt mir helfen.
-
Ich vermute mal, daß du das etwas anders meinst, aber wenn deine Anwendung die Klassen wie in deinem Beispiel bereits kennt, kannst du einfach
new
benutzen:TForm1 *Form1 = new TForm1 (Application);
Oder ist die aus dem Package importierte Klasse, hier TForm1, in deiner Anwendung gar nicht bekannt, so daß dein Code nur die nächstgelegene Basisklasse benutzen kann:
THandle PackageHandle = LoadPackage ("Package"); TClass UnitClass = GetClass ("TForm1"); TForm *Form1; // <-- Application->CreateForm (UnitClass, &Form1);
?
-
Deine zweite Vermutung stimmt genau, aber ich versuch mich etwas konkreter auszudrücken
Die Anwendung importiert die Klassendefinition (.h) von TForm1 (bzw die Basisklasse) per #include. Der Quellcode (.cpp) befindet sich aber nur in der BPL.
Da TForm1 bei der Initialisierung mit
RegisterClass(__classid(TForm1))
registriert wurde, kann ich ja aus der EXE heraus mit CreateForm ein Objekt von TForm1 erzeugen. CreateForm funktioniert aber nur in Verbindung mit Formularen, ich möchte aber auch gerne Nicht-Formular-Klassen verwenden.
-
In C++ gibt es leider nur sehr eingeschränkte Unterstützung für Klassenreferenzen: diese sind anders als in Delphi nur schwach typisiert, d.h. wo du in Delphi
class of TComponent
hast, gibt es in C++ nurTClass
. Deshalb kann man auch keine Klassenfunktionen oder virtuelle Konstruktoren über Klassenreferenzen aufrufen, jedenfalls nicht direkt.Da es in Delphi möglich ist, virtuelle Konstruktoren aufzurufen, kannst du deinem Projekt folgendes Delphi-Unit hinzufügen:
unit Activator; interface (*$HPPEMIT END 'namespace Activator {'*) (*$HPPEMIT END ''*) (*$HPPEMIT END 'template <typename Obj>'*) (*$HPPEMIT END ' Obj* CreateComponent (TClass ClassRef, TComponent* Owner)'*) (*$HPPEMIT END '{'*) (*$HPPEMIT END ' return dynamic_cast<Obj*> (Activator::CreateComponent (ClassRef, Owner));'*) (*$HPPEMIT END '}'*) (*$HPPEMIT END ''*) (*$HPPEMIT END '} // namespace Activator'*) uses Classes; function CreateComponent (ClassRef: TComponentClass; Owner: TComponent): TComponent; implementation function CreateComponent (ClassRef: TComponentClass; Owner: TComponent): TComponent; begin Result := ClassRef.Create (Owner); // das geht in C++ nicht end; end.
In C++ kannst du das dann folgendermaßen benutzen:
#include "Activator.hpp" ... THandle PackageHandle = LoadPackage ("Package"); TClass UnitClass = GetClass ("TForm1"); TForm* Form1 = CreateComponent<TForm> (UnitClass, theOwner);
-
Vielen Dank für deinen Beitrag
Ich hatte schon vermutet, dass das in C++ nicht gehen wird.
Aber deine Lösung gefällt mir sehr gut.