Hallo Andreas,
Danke für Deine Antwort.
Zitat von
jbg:
Du kannst nur über die Extended
RTTI {$METHODINFO ON} auf die public Methoden zugreifen. Properties und Felder sind nicht erreichbar.
Das ist auch die Information, die ich habe. Ich hatte nur die Hoffnung, das man vielleicht doch...
Zitat von
jbg:
Es gibt da immernoch die TD32 DebugInfo Daten, die man anhängen und auslesen kann. Die enthalten dann sogar Informationen über lokale Variaben (die du in deinem Fall wohl ignorieren kannst). Wenn ich mich recht entsinne, nutzt auch TestComplete die TD32 Infos.
Das ist eine gute Idee. Da hat doch mal der Hallvard was in seinem Block geschrieben. Ich werd da mal nachschauen, ob ich da was finde.
[edit]
Ich habe gerade mal auf seinen Blog geschaut, und siehe da, der erste Beitrag ist sein Artikel aus dem Delphi Magazin (Nov 2000) der sich genau damit beschäftigt. -> ich muss mal lesen, ob ich das gebauchen kann.
Link:
http://hallvards.blogspot.com/ (Auf seiner Seite gibt es auch einiges zum Thema
RTTI zu lesen)
[/edit]
Zitat von
jbg:
Ist das nicht einfach nur ein SetMemoryManager(MyMemManRec), wobei man vorher mit GetMemoryManager den alten weggesichtert hat und diesen dann von seinen eigenen MM-Funktionen aus aufruft? Wenn ja, dann sollte das eigentlich nicht wirklich kompliziert sein.
Stimmt, das Hauptproblem wird sein, die Adressen des MemoryManagers der injizierten Applikation zu kommen.
Ziel ist es ja, das
Dll und Applikation denselben verwenden im selben Adressraum. (s.u.)
Zitat von
jbg:
Zitat:
Wie komme ich via
dll-injection an die published / public Eigenschaften der Objekte?
Du musst an die ClassInfo der Klassen rankommen. Wenn die
DLL mit der selben Delphi Version erstellt wurde, sollte das recht einfach zu handhaben sein. Das einzige komplizierte daran ist, an so einen ClassInfo zu kommen. Dazu muss das Programm das Objekt/Instanz an die
DLL schicken, was wohl von dir so nicht angedacht sein dürfte, da du die
DLL ja eigenständig halten willst.
Im Moment machen wir das etwas umständlich.
Da die
dll und die Applikation jeweils eine eigene Instanz, der
RTL /
VCL im Speicher haben, kann man leider auch den "is"-Operator nicht verwenden.
if ObjInApp is TClassInDll then ; // ist immer False, da sie nicht auf den gleichen Speicherbereich zeigen
Aus diesem Grund wird der Vergleich mit der Eigenschaft ClassName vorgenommen. (Also dem String)
Dann wird das Objekt gecastet.
Delphi-Quellcode:
...
if ObjVonApp.ClassName = 'TClassVonDll' then myObjVonApp := TClassVonDll(ObjVonApp);
...
Und genau hier kommt das Problem mit den 2 unterschiedlichen MemoryManagern zum Tragen.
Der Zugriff auf die gecasteten Komponenten ist nicht immer möglich, sondern nur, wenn sie Eigenschaften direkt auf eine Variable verweisen oder die Getter-Methoden statisch (nicht virtuell) sind.
Delphi-Quellcode:
…
private
FGut: string;
FAuchGut: string;
function GetAuchGut: string;
function GetNichtGut: string; virtual;
…
published
property Gut: string; read FGut write SetGut;
property AuchGut: string; read GetAuchGut;
property NichtGut: string; read GetNichtGut;
…
Das liegt daran, das die statischen Methoden im von der
Dll zugreifbaren Adressbereich der Applikation liegen, aber die virtuellen in einem Bereich, auf den die
dll wegen des eigenen MemoryManagers nicht zugreifen kann.
Wie würdest Du das Problem lösen?
Zitat von
jbg:
Zitat:
Kann man evtl. die Probleme umgehen, wenn man ein
Package injiziert?
Dann muss auch die Anwendung gegen Packages kompiliert werden. Die
RTL/
VCL Klassen hättest du dann natürlich leichter im Griff, aber die anderen Klassen musst du wiederum irgendwie "in" das
Package bekommen.
Das deckt sich mit dem was wir auch festgestellt haben.
In einer Anwendung, die gegen
Package kompiliert wurde, kann das
Package leicht geladen und Klassen benutzt werden.
Wird die Anwendung allerdings ohne
Package kompiliert, so kann mit LoadPackage zwar das
Package geladen werden, aber das Benutzen funktioniert nicht mehr so richtig.