AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign verschiedene Klassen via Compiler directive erzeugen
Thema durchsuchen
Ansicht
Themen-Optionen

verschiedene Klassen via Compiler directive erzeugen

Ein Thema von bernhard_LA · begonnen am 26. Mai 2017 · letzter Beitrag vom 26. Mai 2017
Antwort Antwort
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.137 Beiträge
 
Delphi 11 Alexandria
 
#1

verschiedene Klassen via Compiler directive erzeugen

  Alt 26. Mai 2017, 00:12
ich verwenden eine Interface und möchte jetzt über folgendes code Fragment :


Delphi-Quellcode:
{$IFDEF define(encrypt_full)}
  FLicense := Tlicense.create;
{$ELSEIF define(encrypt_tiny)}
  FLicense := TlicenseSimple.create;
{$ELSE}
  FLicense := TlicenseMock.create;
{$IFEND}
ü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.


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 ?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.062 Beiträge
 
Delphi 12 Athens
 
#2

AW: verschiedene Klassen via Compiler directive erzeugen

  Alt 26. Mai 2017, 00:28
Compile oder Build?

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".
Delphi-Quellcode:
{$IF define(encrypt_full)}
  FLicense := Tlicense.create;
...
Oder mmal so probieren.
Delphi-Quellcode:
// 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}
Beim Umstellen ändert sich Unit 1, wird neu kompiliert,
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:
// Unit 2
IF encrypt_full THEN
  FLicense := TLicense.Create
ELSE IF encrypt_tiny THEN
  FLicense := TLicenseSimple.Create
ELSE
  FLicense := TLicenseMock.Create;
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".
Delphi-Quellcode:
const
  encrypt_full: Boolean = False;
  encrypt_tiny: Boolean = True;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (26. Mai 2017 um 00:36 Uhr)
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: verschiedene Klassen via Compiler directive erzeugen

  Alt 26. Mai 2017, 04:38
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}
http://docwiki.embarcadero.com/RADSt...ktive_(Delphi)

http://docwiki.embarcadero.com/RADSt...ktive_(Delphi)

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
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#4

AW: verschiedene Klassen via Compiler directive erzeugen

  Alt 26. Mai 2017, 08:56
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.
Das stimmt so nicht. Folgendes funzt wunderbar:
Delphi-Quellcode:
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.
Im aktuellen Fall ist IFDEF natürlich trotzdem die bessere Wahl.
Uli Gerhardt
  Mit Zitat antworten Zitat
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.137 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: verschiedene Klassen via Compiler directive erzeugen

  Alt 26. Mai 2017, 09:28
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.
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#6

AW: verschiedene Klassen via Compiler directive erzeugen

  Alt 26. Mai 2017, 09:53
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

Das "class" kannst du dir ggfs. noch sparen:
type TLicenseIClass = TLicense; geht auch.
Uli Gerhardt
  Mit Zitat antworten Zitat
bepe

Registriert seit: 17. Okt 2006
119 Beiträge
 
#7

AW: verschiedene Klassen via Compiler directive erzeugen

  Alt 26. Mai 2017, 10:11

Das "class" kannst du dir ggfs. noch sparen:
type TLicenseIClass = TLicense; geht auch.
Im aktuellen Fall sicher ok, vermutlich sogar gewünscht. Generell sollte man, für Mitleser, aber erwähnen dass man ohne Class nur einen Alias definiert.

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)

mfg,
bp
  Mit Zitat antworten Zitat
Antwort Antwort


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 09:43 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