Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Hallo Community,
eigeintlich möchte ich aus Unit_2 heraus feststellen, ob in der benutzten Unit_1 die in der von Unit_1 eventuell benutzte Unit_X eingebunden ist oder nicht. Mir ist dazu nichts besseres eingefallen, als in Unit_X ein passendes Define hinzuzufügen und dieses Define in den rufenden Units abzufragen. Das Gerüst der drei Units sieht dann wie folgt aus:
Delphi-Quellcode:
Mein Problem ist "nur", daß in Unit_2 das
Unit Unit_x;
{$Define Unit_X_ist_Vorhanden} Interface ... Implementation ... End. {Unit_x} {-----------} Unit Unit_1; Interface Uses Unit_X; ... Implementation ... End. {Unit_1} {-----------} Unit Unit_2; ... Interface ... Implementation Uses Unit_1; ... {$IFDEF Unit_X_ist_Vorhanden} // {$ELSE} ShowMessage('Fehler: Unit_X ist NICHT vorhanden!'); {$ENDIF} End. {Unit_2} {-----------}
Delphi-Quellcode:
aus Unit_X nicht sichtbar ist.
{$Define Unit_X_ist_Vorhanden}
Wie könnte ich zu einer praktikablen Lösung kommen? Danke für jeden Tipp & Hinweis im Voraus! |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Mit einem Define geht das nicht und mir fällt auch keine andere Möglichkeit ein, das zu prüfen.
Was willst du denn eigentlich damit erreichen? |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Typen und Konstanten kann man als Alias in Unit1 "neu" deklarieren und sie somit aus UnitX in die Unit2 durchreichen.
Methoden, Property-Typen, Methoden-Result-Typen usw., welche über einen Vorfahren aus UnitX in Unit1 abgeleitet wurden, lassen sich indirekt zugreifen. (so lange man nicht diesen Typen eines Parameter/Result direkt verwenden will) Es gibt ein
Delphi-Quellcode:
, aber damit kannst du nur auf etwas (Variable/Konstante/Funktion/Typ/...) prüfen, welches sich in deinem Scope befindet.
{$IF Declared(...)}
Also eine Unit in einer anderen Unit (egal ob interface oder implementation) findet sich somit nicht. DEFINEs sind nicht modulübergreifend. Ausnahme, wenn sie als Compiler-Option rein kommen. Oder überall via INCLUDE-Datei. Was einfach ginge, zur Laufzeit, nach einem Export oder einer Ressource suchen, welcher über die andere Unit rein kommt. Oder über die erweiterte RTTI etwas davon finden. |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Zitat:
|
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Hey,
Eine Unit hat einen Initialization Abschnitt. Du könntest damit erreichen das sich jede Unit in eine globale Liste einträgt. Später, nachdem alle Units geladen sind, kannst du dann in der Liste nachsehen wer alles da ist. Zwischendurch geht das aber nicht, da es Sache des Compilers/Linkers ist zu entscheiden wann welche Unit geladen/Initialisiert wird. |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Zitat:
Es gibt diese globale Liste bereits. Man kann damit herausfinden, ob eine Unit in ein Executable eingebunden ist oder nicht. Falls es das ist, was der OP erreichen möchte, hier ist Code dafür auf Stack Overflow (als Antwort auf eine Frage, die ich damals gestellt hatte). |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Mir geht es konkret um die Benutzung der von arcticwolf bereitgestellten Bibliothek https://www.delphipraxis.net/213259-...ml#post1524889
Diese Console Library hat für meine unzähligen Test-Berechnungen einige Vorteile (Umlaute, Farben, größere Schrift etc.) gegenüber der Standard-Console. Weil es jedoch bei einer direkten Einbindung von Crt.pas zu Namenskonflikten kommt, habe ich eine Zwischen-Unit angelegt und die für mich wichtigsten Routinen exportiert. Um einfach zwischen der "neuen" und der "alten" Konsole-Ausgabe hin- und herschalten zu können, wollte ich in der Zwischen-Unit die
Delphi-Quellcode:
per Overload in der Weise neu deklarieren, daß bei Abwesenheit der neuen Console Library
Function WriteLn
Delphi-Quellcode:
benutzt wird, ansonsten das neue
System.WriteLn(..)
Delphi-Quellcode:
. Dadurch hätte ich alte Berechnungen wie gehabt und neue mit der neuen Console Library kompilieren können, ohne viel ändern zu müssen.
Crt.WritelnConsole(..)
Wahrscheinlich habe ich viel zu kompliziert gedacht... :oops: Danke für Eure Tipps & Anregungen! :-D |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Zitat:
Es gibt da in der "Console Library" einen Schalter mit dem Du festlegen kannst ob Write/Writeln vom System oder von meiner Library behandelt werden soll. Per Default steht der Schalter auf True. Du kannst ihn mal ausschalten und testen ob das bei deinem Problem hilft.
Delphi-Quellcode:
Console.Modes.UseAlternateWriteProc := False;
Du kannst das entweder direkt beim Start deines Programmes machen oder aber partiell bei einer Funktion, indem Du ihn auf False und danach wieder auf True stellst. |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Wolfgang,
danke für den Hinweis. Leider funktionier es bei mir noch nicht ganz korrekt. Im Anhang ist ein kleines Demo dazu.
Delphi-Quellcode:
ist eine "alte" (= bestehende) Routine, die
PrintVektor(..)
Delphi-Quellcode:
verwendet.
System.WriteLn(..)
Auch wenn ich
Delphi-Quellcode:
einstelle, wird der lange Output von
Console.Modes.UseAlternateWriteProc := False;
Delphi-Quellcode:
gekappt, weil
PrintVektor(..)
Delphi-Quellcode:
nicht in
System.WriteLn(..)
Delphi-Quellcode:
umgeleitet wird, was ich mit meiner ursprünglichen Idee mit der "Zwischen-Unit" realisieren wollte.
Console. WriteLnConsole(..)
|
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Zitat:
Delphi-Quellcode:
verursacht bei mir Probleme, weil dieser Bezeichner bereits in einer von mir anstelle von System.Math.pas benutzten Mathematik-Bibliothek verwendet wird.
MaxX
|
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Zitat:
Mir ist schon vor langer Zeit beim durchsuchen von meinen, mit Delphi erzeugten, Binaries aufgefallen das da die ganzen Unit Namen drinne stehen. Einen Sinn habe ich darin nie gesehen. Ich verwende die Initialization Abschnitte auch nicht zum sammeln von Unit Namen, wozu auch ;-). Sondern zum registrieren von Funktionen oder Klassen für automatische Konverter/etc. |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Jupp, diese Liste wird benutzt, um beim Start alle Initialization und am Ende alle Finalization zu durchlaufen.
Aber dort stehen nicht ALLE Units drin, vor allem nicht, wenn sie weder Initialization/Finalization, Class-Constructor/Destructor oder globale Variablen haben, weil dann ist es ja nicht nötig was zu machen. Auch in den Ressourcen der EXE/DLL findet sich was, wo die Units aufgelistet werden. Dann die Debuginfos als PE-Section. Oder, wie schon gesagt, über TRTTI danach suchen. |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Zitat:
|
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Zitat:
|
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Du baust also extra einen Code, der speziell nach dieser Unit sucht (oder Irgendeiner, die zufällig gleich heißt, aber was ganz Anderes ist),
um mit dieser Info dann was zu machen. Warum dann nicht diese Info direkt reinschreiben? Wenn, dann wäre es besser, wenn der Entwickler eine standardisierte Credits-Ressource bei legt, oder z.B. ein standardisiertes Credits-Attribut an seine Unit/Klasse/Sonstwas hängt, die man dann leicht finden könnte. |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Zitat:
|
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Zitat:
Du denkst da ein bisschen kompliziert, eine ganze Unit brauchst Du dafür nicht ;-). Vorab mal ein paar Fragen/Hinweise: - Brauchst Du wirklich eine Zeilenlänge von 1.200 Zeichen und 15.000 Zeilen? -> Console.Buffer(10*120,10*1500, True); :? - Du solltest beim Start immer die Größe des Konsolenfensters also den sichtbaren Bereich festlegen, z.B. auf 120 x 50 mit Console.Window(120,50). Sonst nimmt Windows einen Wert aus der Registry und der kann wenn deine Anwendung mal auf einem anderen Rechner läuft ein ganz anderer sein. - In der Funktion "PrintVektor" verwendest Du System.Writeln, für die Ausgabe der Zeilen Crt.WritelnConsole. Wie ich im anderen Beitrag geschrieben habe, geht dieser Mix nicht. Zitat:
Wenn Du also diesen Ansatz (Vergrößerung des Puffers) verfolgen möchtest, dann leite doch einfach "System.Write & System.Writeln" direkt auf die Crt.WriteConsole um. 1. Eigene Funktion erstellen
Delphi-Quellcode:
2. System.AlternateWriteUnicodeStringProc auf deine Funktion umleiten
Function CrtWriteAlternateConsole(var t: TTextRec; s: UnicodeString) : Pointer;
begin WriteConsole(s); Result := @t; end;
Delphi-Quellcode:
AlternateWriteUnicodeStringProc := @CrtWriteAlternateConsole;
Fertig ist der Zauber. Dann ist es auch egal ob du Writeln oder WritelnConsole verwendest, abgesehen davon, dass der direkte Aufruf von WritelnConsole natürlich schneller ist als der Umweg über System.Writeln. Ja OK, hört sich jetzt trivial an, ist es auch, zumindest für Dich. Die Arbeit im Hintergrund übernimmt dann automatisch meine "Console Library" 8-). Das Ganze sieht dann in etwa so aus:
Delphi-Quellcode:
Das ist natürlich eine verkürzte Darstellung aber ich denke Du bekommst das hin.
AlternateWriteUnicodeStringProc := @CrtWriteAlternateConsole;
Textcolor(Yellow); TextBackground(Blue); Console.Font.SetDefault; Console.Window(120,50); EnlageBufferSize; FillVektor(Vektor, 2); PrintVektor(Vektor, 'Vektor'); For Zeile:= 1 To 200 Do Begin WriteLnConsole('Zeile[' + Zeile.ToString.PadLeft(3) + ']'); End; Console.ReadkeyScroll(Key); Disclaimer: Das mit dem vergrößertem Puffer und WriteConsole ist von mir weder getestet noch im produktivem Einsatz gewesen. Das war/ist nur eine Idee von mir wie du ein Problem lösen könntest. Ich würde mich jedoch über Berichte freuen, ob das stabil läuft oder ob es Probleme gibt. Gerne auch per PM oder E-Mail (findest Du auf GitHub). |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Vielen herzlichen Dank für Deine & Eure Unterstützung & Erläuterungen! :thumb: :thumb: :thumb:
"Kaum macht man es richtig, schon klappt es." :-D Es tut mir leid, daß ich Eure Zeit mit meinem Kinderkram verplempere... :oops: |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Zitat:
(Hint: Ein Quote hätte hier Klarheit geschaffen.) Da die Entwickler diese Ressource nicht zur Verfügung stellen und ich nicht an deren Code rumfummeln will, war die Suche nach einer Unit, die beim Einbinden einer Bibliothek immer vorhanden ist, die einfachste Lösung. Und da die meisten Bibliotheken ein individuelles Prefix im Unit-Namen verwenden, ist das auch ziemlich eindeutig. |
AW: Unit-übergreifende Sichtbarkeit von {$Define …} - geht das?
Das bezog sich eigentlich auf "alle" Entwickler von Komponenten :)
Und wie schon erwähnt, kannst'e bei vielen Komponenten auch nach einer derer Ressourcen suchen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:42 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