AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

mit string an PTypeinfo rankommen

Ein Thema von _frank_ · begonnen am 27. Apr 2006 · letzter Beitrag vom 27. Apr 2006
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#1

mit string an PTypeinfo rankommen

  Alt 27. Apr 2006, 13:36
hallo,
vor dem Kompilieren kann man sich die Typinfos (z.B. um die werte eines Enums zu bekommen) per TypeInfo holen, dieses funktioniert aber nicht zur Laufzeit. Ich brauche dies aber dynamisch zur Laufzeit.
Momentan fülle ich ein array of PTypeinfo aller mir bekannten typen per Typeinfo.

gibt es eine möglichkeit per typ-string an diesen Pointer zu kommen?

Gruß Frank
Frank Wunderlich
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.416 Beiträge
 
Delphi XE5 Professional
 
#2

Re: mit string an PTypeinfo rankommen

  Alt 27. Apr 2006, 13:46
es kann nicht funktionieren, da die typinfos erst beim kompilieren erzeugt werden.

du kannst versuchen über die ide interfaces an den source/parser zu kommen und das dann auslesen.
schliesslich tut das ja auch der code-explorer
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#3

Re: mit string an PTypeinfo rankommen

  Alt 27. Apr 2006, 14:11
Damit http://www.delphipraxis.net/internal...065&highlight= funktioniert das.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#4

Re: mit string an PTypeinfo rankommen

  Alt 27. Apr 2006, 14:21
schaue grade ob ich die unter D3 zum Laufen bekomme, das es keine dynamischen arrays, default-werte, overload etc gibt...
Frank Wunderlich
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#5

Re: mit string an PTypeinfo rankommen

  Alt 27. Apr 2006, 14:38
Uff, das ist im Falle dieser Unit aber schlecht.

Extrahiere dir meine Funktion EnumTypeInfos(). Diese enthält den entscheidenden Trick und der Rest ist nur ein komfortabler Überbau -> Hilfsfunktonen.

Auf alle Fälle kannst du nun über alle RTTI Records der Module iterieren. Mit PTypeInfo^.Name kannst du dabei einen Vergleich mit deinem Suchstring anstellen und findest auf diese Weise den PTypeInfo Zeiger zu deinem Namen einer TypInfo.

Beachte dabei das es sehr wohl zulässig ist zwei unterschiedliche Typen mit gleichem Namen aber in unterschiedlichen Units zu deklarieren. Dh. der reine Name eines Types ist nicht eineindeutig !! Erst die Verknüfpung von Modulname + Unitname + Typname ist eineindeutig.

Gruß Hagen
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.416 Beiträge
 
Delphi XE5 Professional
 
#6

Re: mit string an PTypeinfo rankommen

  Alt 27. Apr 2006, 14:43
http://www.instantobjects.org/

haben ein ide plugin welches das über die toolsapi löst.
bin auf die schneller aber nicht dahinter gekommen welches interface genutzt wird.

[edits]
vergesst mal meine posts, ich bin im büro halbschlaf.
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#7

Re: mit string an PTypeinfo rankommen

  Alt 27. Apr 2006, 14:49
Mit der normalen RTTI ist das wohl nicht möglich?

habs mal so probiert:

Delphi-Quellcode:
//longword => integer

function FindTypeInfo(const ATypeName: string): PTypeInfo;

type
  TEnumTypeInfoFunc = function(AUserData: Pointer; ATypeInfo: PTypeInfo): Boolean; register;

  //findtypeinfo

function EnumTypeInfos_base(AModule: integer; AFunc: TEnumTypeInfoFunc; AUserData: Pointer): PTypeInfo;
// copyright (c) 1998 Hagen Reddmann

  function GetBaseOfCode(AModule: integer; var ACodeStart, ACodeEnd: PChar): Boolean; register;
  // get Codesegment pointers, check if module is a valid PE
  asm
           PUSH EDI
           PUSH ESI
           AND EAX,not 3
           JZ @@2
           CMP Word Ptr [EAX],'ZM';
           JNE @@1
           MOV ESI,[EAX + 03Ch]
           CMP Word Ptr [ESI + EAX],'EP'
           JNE @@1
           MOV EDI,[EAX + ESI + 014h + 008h]
           ADD EAX,[EAX + ESI + 014h + 018h]
           ADD EDI,EAX
           MOV [EDX],EAX
           MOV [ECX],EDI
           XOR EAX,EAX
    @@1: SETE AL
    @@2: POP ESI
           POP EDI
  end;

type
  PLongWord = ^integer;
  PByte = ^Byte;
var
  P,E,K,N: PChar;
  L: Integer;
begin
  Result := nil;
  try
    if GetBaseOfCode(AModule, P, E) then
      while P < E do
      begin
        integer(P) := integer(P) and not 3;
        K := P + 4;
        if (PLongWord(P)^ = integer(K)) and (TTypeKind(K^) >= Low(TTypeKind)) and (TTypeKind(K^) <= High(TTypeKind)) then
        begin
          L := PByte(K + 1)^; // length Info.Name
          N := K + 2; // @Info.Name[1]
          if (L > 0) and (N^ in ['_', 'a'..'z', 'A'..'Z']) then // valid ident ??
          begin
            repeat
              Inc(N);
              Dec(L);
            until (L = 0) or not (N^ in ['_', 'a'..'z', 'A'..'Z', '0'..'9']);
            if L = 0 then // length and ident valid
              if not Assigned(AFunc) or AFunc(AUserData, Pointer(K)) then // tell it and if needed abort iteration
              begin
                Result := Pointer(K);
                Exit;
              end else K := N;
          end;
        end;
        P := K;
      end;
  except
  end;
end;

function EnumTypeInfos(AFunc: TEnumTypeInfoFunc; AUserData: Pointer): PTypeInfo;
type
  PModulesEnumData = ^TModulesEnumData;
  TModulesEnumData = packed record
    AFunc: TEnumTypeInfoFunc;
    AUserData: Pointer;
    AResult: PTypeInfo;
  end;

  function EnumTypeInfosInModule(AModule: integer; AData: PModulesEnumData): Boolean; register;
  begin
    with AData^ do
    begin
      AResult := EnumTypeInfos_base(AModule, AFunc, AUserData);
      Result := AResult = nil;
    end;
  end;

var
  Data: TModulesEnumData;
begin
  Data.AFunc := AFunc;
  Data.AUserData := AUserData;
  Data.AResult := nil;
  EnumModules(TEnumModuleFunc(@EnumTypeInfosInModule), @Data);
  Result := Data.AResult;
end;

function IsTypeCorrespondingToName(AName: Pointer; ATypeInfo: PTypeInfo): Boolean; register;
begin
  Result := AnsiCompareText(PChar(AName), ATypeInfo.Name) = 0;
end;

function FindTypeInfo(const ATypeName: string): PTypeInfo;
begin
  Result := EnumTypeInfos(IsTypeCorrespondingToName, PChar(ATypeName));
end;
leider ist z.B. FindTypeInfo('TBorderIcon') = nil
sollte abr nicht so sein

Gruß Frank
Frank Wunderlich
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#8

Re: mit string an PTypeinfo rankommen

  Alt 27. Apr 2006, 16:29
Ich kann beim Überfliegen deines Source jetzt keinen Fehler entdecken. Du solltest die HTML Tags hier benutzen damit dein Source besser lesbar ist. Einfach im Editor oben den Button "Delphi-Code" drücken.

Kann es sein das der Typ "TBorderIcons" heist ?

Zitat:
Mit der normalen RTTI ist das wohl nicht möglich?
Nein. Nach persönlicher Aussage einiger Borland Programmierer in den Newsgroups mir gegenüber, ist es definitiv überhaupt nicht möglich was mein Code da macht. So kann man sich irren

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von _frank_
_frank_

Registriert seit: 21. Feb 2003
Ort: Plauen / Bamberg
922 Beiträge
 
Delphi 3 Professional
 
#9

Re: mit string an PTypeinfo rankommen

  Alt 27. Apr 2006, 16:38
ich hab im gegensatz zu deinem source Longword durch integer (32bit) ersetzt, das PLongword als ^Integer definiert und die ursprungsfunktion _base genannt, da es kein overload gibt.

wegen dem Bordericon (definition von TForm.Bordericons):
Delphi-Quellcode:
type
TBorderIcon = (biSystemMenu, biMinimize, biMaximize, biHelp);
TBorderIcons = set of TBorderIcon;
somit müsste TBordericon funktionieren (hab auch +s probiert, das gleiche Resultat)

Gruß Frank
Frank Wunderlich
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#10

Re: mit string an PTypeinfo rankommen

  Alt 27. Apr 2006, 17:16
Ich habe deinen Source 1 zu 1 nun mal in Delphi 5 und Delphi 3 getestet. Jeweils ohne und mit Packages. Es funktionierte immer egal ob ich TBorderIcon oder TBorderIcons benutze.

Es sieht wohl so aus das du Unit Forms.pas garnicht in deinem Projekt benutzt und der Compiler somit auch nicht den Typ TBorderIcon einlinkt.

Obige Methode kann ja nur RTTIs finden die auch im Program verwendet werden !!

Am besten kompilierst du dein Projekt mal mit Packages so das Package VCL30.dpl auch eingelinkt wird. Dann müsste deine obige Funktion auch diese RTTI finden da nun der Compiler/Linker diesen Typ nicht mehr aus dem VCL30 Package "weg-linken" kann

Mit GetModuleFindName(FindHInstance(PTypeInfo), xzy); kannst du dann sehen das diese RTTI im Codesegment des Packages VCL30 abgelegt ist.

Gruß Hagen

[edit]
Und nochwas !! Kann es sein das du diese Funktion in eine DLL augelagert hast ? Das kann dann nicht funktioinieren da dann nur die RTTI innerhalb dieser DLL iteriert wird. Du müsstest das Modul-Handle -> HInstance des Prozesses dazu haben und an EnumTypeInfo() übergeben. Bei einer DLL die Packages benutzt und die Hauptanwendung benutzt die gleichen Packages wird EnumModules() innerhab der DLL auf die gleichen globalen Datenstrukturen zugreifen wie der Hauptprozess. Dh. in diesem Moment hat diese DLL auch Zugriff auf die Liste aller geladenen Module im Prozess und kann somit auch alle RTTIs finden.
Falls du NICHT mit Packages arbeiten möchtest aber denoch eine DLL benutzen willst so kann ich dir einen weiteren Trick geben der denoch alle Module des Prozesses itererien kann.
[/edit]
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:35 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