PreCompiler für OOP und Include-Libraries

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

PreCompiler für OOP und Include-Libraries

Beitrag von GPI »

Die bisherigen OOP-Lösungen hatten immer Nachteile. Beispielsweise konnte eine Methode völlig andere Parameter haben, als in Interface angegeben. Das kann zu ziemlich blöden Programmierfehlern führen, die man ewig sucht. Aus dieser Idee ist der PreCompiler entstanden, der mittlerweile "eskaliert" ist und ein paar Sachen mehr kann.

Was kann mein PreCompiler:
  • Unterstützung für OOP
  • Erstellung von Fake-Libraries
  • Bei der Erstellung von DLLs werden Import-Dateien erstellt
  • Erstellung eines PreProcess, der ohne PreCompiler weiterverarbeitet werden kann.
  • Original-Dateien werden nicht verändert
  • Fehlermeldungen werden von der IDE an der richtigen Stelle angezeigt
  • Läuft auf Mac und WIndows
Für eine Linux-Version fehlt mir eine Linux-Installation (und Geduld mich da auch einzuarbeiten). Prinzipiell ist der PreCompiler allerdings darauf vorbereitet. Es muss eigentlich nur an Anfang ein Block erstellt werden, der die Linux-Definitionen enthält.

Was sind Include-Libraries
Leider kann ich keine echten Libraries anbieten, das hier kommt am nächsten ran. Der prinzipielle Aufbau einer Include-Library entspricht einer DLL. Der PreCompiler erkennt automatisch in Quellcode, ob diese Library gebraucht wird und fügt automatisch hinzu.

Wie funktioniert OOP?
Ich geh davon aus, dass OOP prinzipiell bekannt ist. Eine Klasse wird so definiert:

Code: Alles auswählen

Interface <Klassenname>  [extends <Parent>]
  <methode>
EndInterface
Structure s<Klassenname> [extends s<Parent>]
  <member>
EndStructure
DeclareClass(<Klassenname>[,<Parent[,AllowNull]])

DefineClass(<Klassenname>[,<Parent[,AllowNull]])
Procedure <Klassenname>_<Methode>(*Self.s<Klassenname> ...)
EndProcedure
DeclareClass ist optional. Wird bspw. benötigt, wenn man eine Klasse in einen Modul erstellen will. AllowNull kann #True oder #False sein. Damit wird erlaubt, Methoden nicht zu definieren. Ansonsten meckert der PreCompiler an, das Methoden fehlen. AllowNull wird nicht vererbt.

Neben den bekannten Methoden gibts eine Reihe von Spezialfällen:
Die Konstruktoren: Bei Erfolg muss ein #true zurückgeben werden.

Code: Alles auswählen

_Constructor(*self)
_ConstructorEx(*self,*para)
<Klassenname>(*self)
<Klassenname>Ex(*self,*para)
Die Destruktoren:

Code: Alles auswählen

_Destructor(*self)
De<Klassenname>(*self)
Der Copy-Constructor: Bei Erfolg muss ein #True zurückgegeben werden

Code: Alles auswählen

_CopyConstructor(*self)
Die OOP-Funktionen des PreCompilers unterstützen ein Parameter für die Klassenerstellung.

Ein Object wird mit

Code: Alles auswählen

<Klassenname>\new( [*para] )
erstellt. Entweder bekommt man das Objekt zurück oder #Null.

Freigeben geht mit

Code: Alles auswählen

FreeObject( <Objekt> )
eine Kopie eines Objekts lässt sich mit

Code: Alles auswählen

CopyObject( <Objekt> )
erstellt werden - falls unterstützt!

Weitere Funktionen

Code: Alles auswählen

<Klassenname>\IsAccessable( <Objekt> )
Gibt #True zurück, wenn das Objekt mittels dieser Klasse angesprochen wird. Das Objekt muss nicht zwingend zur angegeben Klasse gehören!

Code: Alles auswählen

<Klassenname>\IsClass( <Objekt> )
Gibt #True zurück, wenn das Objekt genau die angegebene Klasse entspricht.

Zusätzlich gibt es zwei Konstanten

Code: Alles auswählen

#<Klassenname>_NameTable
#<Klassname>_ParaTable
Sie enthalten die Namen (getrennt durch ;) von jeder Methode der Klasse und die Parameter (ebenfalls mit ; getrennt).
Nicht benötigte Konstanten werden durch den PreCompiler entfernt, so dass diese eine fertige Exe nicht aufblähen.

Wie erstelle ich eine IncludeLibrary?
Prinzipiell schreibt man eine normale DLL mit ProcedureDLL etc. Der SourceCode für eine solche Library hat idealerweise eine Endung ".pbLib". Der PreCompiler zerlegt dann das ganze und speichert sie ab. Das muss für jede PureBasic-Version durchgeführt werden. Dabei gibt es folgende zusätzliche Befehle:

Code: Alles auswählen

ResidentExport
...
EndResidentExport
Aus den Code-Segment zwischen den beiden Steuerwörtern wird eine .res - Datei für den Compiler erstellt. Es sind Macros, Structuren, Interfaces und Konstanten erlaubt. Alles andere führt zu einer Fehlermeldung. Durch die res - Datei wird das überall verfügbar, sogar in jeden Modul. Ist also mit Vorsicht zu genießen.

Code: Alles auswählen

ExportClass( <Klassenname> )
Exportiert eine Klasse. Der Interface-EndInterface und Structure-EndStructure-Bereich wird in die Res-Datei gepackt. Eine exportierte Klasse kann als Parent nach Extends dienen. Wichtig: man muss eine "NEW"-Procedure schreiben, um ein Objekt erzeugen zu können!

WICHTIG!
In IncludeLibraries dürfen keine Module verwendet werden. Sie werden auch von PreCompiler entsprechend mit einer Fehlermeldung quittiert.
IncludeLibraries dürfen aber durchaus andere IncludeLibraries benutzen (inklusive deren exportieren Klassen). Wenn man eine Library ändert, sollte man alle davon abhängigen auch neu erstellen.

Was ist das automatische erstellen einer Importdatei bei DLL-Erstellung?
Wenn eine DLL erstellt wird, wird automatisch eine Datei mit einen Import-EndImport-Block erstellt. Der Name ist simpel <DLL-Name>.imp.pb.
Sie liegt da wo die .DLL,.LIB und .EXP (Windows) liegt.

Was muss man beachten
Durch die Art und Weise wie der PreCompiler arbeitet, darf in der ersten Zeile der Hauptdatei keine PreCompiler-Spezifischen Sachen oder IncludeLibraries benutzt werden. In der zweiten Zeile gibt es keine Probleme. Falls man das nicht beachtet, dann bekommt man einen Modul-Fehler.
IncludePath funktioniert mit relativen Angaben mehr in der Hauptdatei. Am besten vermeidet man diesen Befehl einfach komplett.
Der PreCompiler ist für 5.61 und höher geschrieben und geht davon aus, dass mit Unicode compiled wurde. Was anderes geht ja auch nicht.

Bei Libraries gibts die Einschränkung, dass sie nicht in einen Modul sein dürfen. Der PreCompiler verpackt sie dinger ja selbst in Module und Module in Module geht nicht.

Für beides wichtig: UNICODE ist Pflicht!

Wie richte ich den PreCompiler ein - Automatische Version
Einfach eine ausführbare Datei erstellen (ich empfehle einen leeren Ordner) und normal ausführen. Es sollte ein Quicksetup sich öffnen. Da auf Installieren klicken.

Wie richte ich den PreCompiler ein - Manuelle Version
Als erstes sollte man der IDE die Endung "pbLib" beibringen. Unter "File>Preferences..." in Bereich "Editor" "Code file extensions" die Endung "pbLib" hinzufügen.

Den SourceCode für den PreCompiler kompilieren und ihn in Tools-Menü eintragen. Es sind 4 Einträge nötig.
Eintrag 1:
Der erfüllt eine Doppelfunktion. Einmal wird hier der PreCompiler gestartet, wenn man Compile/Run ausführt. Zum anderen kann hiermit ein PreProcess erzeugt werden, wenn man ihn direkt aus den Menü aufruft. Es wird dann eine "<Dateiname>.PreProcess.pb" erstellt.
  • Commandline = <Precomiler.exe>
  • Arguments = "%FILE" "%COMPILEFILE" "%EXECUTABLE"
  • WorkingDirectory = <Verzeichnis wo die FakeLibraries gespeichert werden sollen>
  • Name = PreCompiler
  • Event to trigger the tool = Before Compile/Run
  • Wait until Tools end = Checked
Eintrag 2
  • Commandline = <Precomiler.exe>
  • Arguments = "%FILE" "%COMPILEFILE" "%EXECUTABLE"
  • WorkingDirectory = <Verzeichnis wo die FakeLibraries gespeichert werden sollen>
  • Name = PreCompiler Executable
  • Event to trigger the tool = Before Create Executable
  • Wait until Tools end = Checked
  • Hide Tool from Main Menu = Checked
Eintrag 3
  • Commandline = <Precomiler.exe>
  • Arguments = "%FILE" "%COMPILEFILE" "%EXECUTABLE" CreateLib
  • WorkingDirectory = <Verzeichnis wo die FakeLibraries gespeichert werden sollen>
  • Name = PreCompiler Create Lib
  • Event to trigger the tool = Menu or Shortcut
Eintrag 4
  • Commandline = <Precomiler.exe>
  • Arguments = "%FILE" "%COMPILEFILE" "%EXECUTABLE" DeleteLib
  • WorkingDirectory = <Verzeichnis wo die FakeLibraries gespeichert werden sollen>
  • Name = PreCompiler Create Lib
  • Event to trigger the tool = Menu or Shortcut
Der PreCompiler braucht für OOP unbedingt die libClass.pbLib. Den SourceCode unten einfach speichern und über den Menüeintrag in eine FakeLib umwandeln. Wenn die Source-Datei die Endung .pbLIB hat, reicht auch ein drücken auf F5 für Compile/Run.

Jetzt muss man nur in Compiler-Menü den Compiler neu starten.

Wichtig zu wissen: Der PreCompiler kann sowohl 32Bit als auch 64Bit sein. Er kann dann beides behandeln. Man muss als nicht für jeder Bit-Version eine eigene Exe erstellen werden. Genauso das Verzeichnis für die FakeLibraries kann für alle gleich sein. Die Namen werden anhand des Betriebsystems und der Compilerversion gewählt und überschneiden sich nicht.

Jetzt gehts weiter mit den Quelldateien.
Zuletzt geändert von GPI am 15.10.2017 18:43, insgesamt 3-mal geändert.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: PreCompiler für OOP und "Fakelibs"

Beitrag von GPI »

Zuletzt geändert von GPI am 15.10.2017 18:43, insgesamt 2-mal geändert.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: PreCompiler für OOP und "Fakelibs"

Beitrag von GPI »

<reserviert>
Zuletzt geändert von GPI am 15.10.2017 18:43, insgesamt 2-mal geändert.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: PreCompiler für OOP und "Fakelibs"

Beitrag von GPI »

<reserviert>
Zuletzt geändert von GPI am 15.10.2017 18:44, insgesamt 3-mal geändert.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: PreCompiler für OOP und "Fakelibs"

Beitrag von GPI »

<reserviert>
Zuletzt geändert von GPI am 15.10.2017 18:44, insgesamt 3-mal geändert.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: PreCompiler für OOP und "Fakelibs"

Beitrag von GPI »

<reserviert>
Zuletzt geändert von GPI am 15.10.2017 18:44, insgesamt 2-mal geändert.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: PreCompiler für OOP und "Fakelibs"

Beitrag von RSBasic »

Danke für die vielen Beispielcodes. Sieht sehr interessant aus. :allright:
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: PreCompiler für OOP und "Fakelibs"

Beitrag von GPI »

RSBasic hat geschrieben:Danke für die vielen Beispielcodes. Sieht sehr interessant aus. :allright:
Wenn du fragen hast, meld dich ruhig. Ich bin nicht so gut beim erklären...

Der Code ist leider nicht der sauberste, das Ding ist ziemlich wild gewachsen und 10x umgeschrieben worden (früher arbeitete er mit DLLs).
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: PreCompiler für OOP und "Fakelibs"

Beitrag von GPI »

So 1.1 ist draußen. Ich hab *alles* überarbeitet. Der Quellcode ist jetzt deutlich sauberer. Die Option "Datasection" wurde entfernt, da diese eh durch einen PB-Bug nicht optimal nutzbar ist und beim Mac in dylibs Probleme macht.
Die Dokumentation oben hab ich auch überarbeitet. Ich hatte bspw. die beiden Konstanten #<Klassenname>_NameTable und #<Klassname>_ParaTable vergessen. Braucht man vermutlich zu 99% nie, aber in den 1% der Fälle sind sie sehr wertvoll.
Die Libs werden jetzt auch in einen anderen Format gespeichert. Müssen also alle neu erstellt werden. Die Libs wurden auch alle überarbeitet.

Ich hoffe das ganze ist jetzt deutlich klarer.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: PreCompiler für OOP und Include-Libraries

Beitrag von GPI »

So, ich hab die Dateien in eine handliche 7z gepackt:
http://game.gpihome.eu/PureBasic/PreCompiler/

;changelog
; 1.2
; - Installation-Script
; - Removed DataSection/EndDataSection
; - Declares of the methodes are now in DefineClass. DefineClass should be now before all methods.
; - Comments in Preprocess aren't removed anymore

Wenn wer schon IncludeLibraries erstellt hat, muss sie erneut durch den PreCompiler jagen. Das interne Format hat sich geändert.

Wenn wer in Linux arbeitet - mich würde es freuen, wenn es wer anpassen würde. Normalerweise in PreCompiler.pb an Anfang einen Block Linux hinzufügen. Zum größten Teil kann man wohl einfach den Mac-Bereich kopieren.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Antworten