![]() |
verschiedene Klassen via Compiler directive erzeugen
ich verwenden eine Interface und möchte jetzt über folgendes code Fragment :
Delphi-Quellcode:
über die Einstellungen der Projektoptionen beim Compilieren die jeweilige Klasse erzeugen. Diese FLicense Klasse wird in mehreren Forms / units verwendet. Dort habe ich überall diesen Code eingebaut.
{$IFDEF define(encrypt_full)}
FLicense := Tlicense.create; {$ELSEIF define(encrypt_tiny)} FLicense := TlicenseSimple.create; {$ELSE} FLicense := TlicenseMock.create; {$IFEND} Problem : Egal was ich als Conditional define Parameter beim Compilieren auswähle, es wird immer nur die TlicenseMock Klasse erzeugt. Was mache ich falsch, wie erreiche ich mein Ziel ? |
AW: verschiedene Klassen via Compiler directive erzeugen
Compile oder Build? :zwinker:
Der Compiler erzeugt von sich aus Units nur neu, wenn sie sich verändert haben und das tun sie hier nicht, also mußt DU explizit zwangsweise neu compilieren, also "alles neu erzeugen". Ganz fies, wenn man solche DEFINES in den Projektoptionen umstellt, wo sich an den Code-Dateien dann garnichts ändert. Aber sicher, dass dein Code so funktioniert? $IFDEF prüft nur DEFINES, aber du willst CONDITIONAL-EXPRESSIONS auswerten und das macht man mit $IF. Wenn der Parser echt doof ist und sowas durch lässt, dann könnten deine DEFINEs "define(encrypt_full)" und "define(encrypt_tiny)" heißen, anstatt "encrypt_full" und "encrypt_tiny". :freak:
Delphi-Quellcode:
Oder mmal so probieren.
{$IF define(encrypt_full)}
FLicense := Tlicense.create; ...
Delphi-Quellcode:
Beim Umstellen ändert sich Unit 1, wird neu kompiliert,
// Unit 1 oder Include 1
const encrypt_full = False; encrypt_tiny = True; // Unit 2 {$IF encrypt_full} FLicense := TLicense.Create; {$ELSEIF encrypt_tiny} FLicense := TLicenseSimple.Create; {$ELSE} FLicense := TLicenseMock.Create; {$IFEND} und mit etwas Glück erzwingt das auch ein Neukompilieren von Unit 2. So muß es auf jeden Fall neu kompilieren und die Code-Optimierung müsste schlau genug sein und alle nichtbenötigten Zweige entfernen. (bei "echten" Konstanten)
Delphi-Quellcode:
Was durch typisierte Konstanten passiert, könnte noch interessant sein, da das in Wirklichkeit nur "schreibgeschützte" Variablen sind, deren eine Speicherstelle man dennoch verändern "könnte".
// Unit 2
IF encrypt_full THEN FLicense := TLicense.Create ELSE IF encrypt_tiny THEN FLicense := TLicenseSimple.Create ELSE FLicense := TLicenseMock.Create;
Delphi-Quellcode:
const
encrypt_full: Boolean = False; encrypt_tiny: Boolean = True; |
AW: verschiedene Klassen via Compiler directive erzeugen
Das define in der if ist zuviel :)
Richtig wär:
Delphi-Quellcode:
// Unit 1 oder Include 1 //const // encrypt_full = False; // encrypt_tiny = True; {.$DEFINE encrypt_full} {$DEFINE encrypt_tiny} // Unit 2 {$IFDEF encrypt_full} FLicense := TLicense.Create; {$ELSEIF encrypt_tiny} FLicense := TLicenseSimple.Create; {$ELSE} FLicense := TLicenseMock.Create; {$IFEND} ![]() ![]() Ein Zugriff auf "normale" Code-Konstanten innerhalb einer Compiler-Direktive ist logischerweise nicht möglich, das sie ja erst während des compilierens angelegt wird und so ggf. dem Compiler garnicht bekannt ist. Alternativ zu den DEFINES in Unit1 kannst du das entsprechende Symbol auch über die Projektoptionen (Delphi-Compiler->Bedingungen) definier. Dazu einfach das gewünschte Symbol mit einem ; anhängen (BSP.: DEBUG;encrypt_tiny) Hoffe mal das hilft dir weiter :) |
AW: verschiedene Klassen via Compiler directive erzeugen
Zitat:
Delphi-Quellcode:
Im aktuellen Fall ist IFDEF natürlich trotzdem die bessere Wahl.
program Project1;
{$APPTYPE CONSOLE} uses SysUtils; {$DEFINE TEST1} const Test2 = 10; begin try {$IFDEF TEST1} Writeln('Test1'); {$ENDIF} {$IF Declared(Test2)} Writeln('Test2 declared'); {$IFEND} {$IF Test2>5} Writeln('Test2 biiiig'); {$IFEND} Readln; except on E: Exception do Writeln(E.Classname, ': ', E.Message); end; end. |
AW: verschiedene Klassen via Compiler directive erzeugen
habe mir jetzt eine separate unit angelegt und definiere eine Interface-Alias-KlassenNamen- Klasse, damit ist dann nur eine Stelle + eine Zeile {$define .... } im Code anzupassen wenn ich die Klasse tauschen will und auch nur eine Zeile code in den Units die meine Interface Klasse verwenden
Delphi-Quellcode:
unit Unit_TlicenseAlias;
interface uses ...... ; {$define encrypt_tiny} {$IFDEF encrypt_full} Type TLicenseIClass =class( Tlicense); {$ifend} {$IFDEF encrypt_tiny} Type TLicenseIClass =class( TlicenseSimple); {$ifend} {$IFDEF encrypt_Mock} Type TLicenseIClass = class(TlicenseMock); {$IFEND} implementation end. |
AW: verschiedene Klassen via Compiler directive erzeugen
Zitat:
Das "class" kannst du dir ggfs. noch sparen:
Delphi-Quellcode:
geht auch.
type TLicenseIClass = TLicense;
|
AW: verschiedene Klassen via Compiler directive erzeugen
Zitat:
Delphi-Quellcode:
type TLicenseIClass = TLicense; // ob man später TLicenseIClass oder TLicense verwendet macht keinerlei Unterschied (TLicenseIClass = TLicense: True)
type TLicenseIClass = class(TLicense); // hier ist TLicenseIClass eine eigenständige Klasse, welche von TLicense erbt (TLicenseIClass = TLicense: False) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:40 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz