8.5.2 Aufbau und funktionale Zusammenhänge im IS
Das Interpretersystem ist als separate DLL realisiert. Die Anwendungsschnittstelle zum Anwendungsprogramm fällt relativ klein aus. Benötigt werden die Klasse ACIpsInstance und ACIpsData, definiert in acips.hpp und acipsdat.hpp..
Möchte ein Programmierer das Buchungssystem nutzen, so mu je ein Objekt dieser beiden Klassen angelegt werden und im einfachsten Fall kann der Buchungsvorgang sofort ausgelöst werden.
Beispiel:
Programmfunktion()
{
ULONG xRechung = 112;
ACIpsData IpsData;
ACIpsInstance Buchung()
ACIpsError &EO = Buchung.QueryErrorObject();
EO.Clear();
Buchung.SetApplHandle(ulMyApplHndl);
SCString scsScriptFile = "D:\\BS463.BSD";
if ( !Buchung.Run(scsScriptFile,IpsData) )
{
EO.BuildMsgText();
SCString scsErrorMsg;
EO.QueryMsgText(scsErrorMsg);
SvcMessageBox(ulMyApplHndl,(pCHAR)scsErrorMsg,0);
BOOL bAppend = TRUE;
KCProt CProtokoll(strErrdat,bAppend);
EO.QueryMsgText(scsErrorMsg,IPSSEF_StripFromLF);
scsErrorMsg += "\n";
if ( !CProtokoll.Write(scsErrorMsg) )
; //z.B. Messagebox mit Meldung, das Ausgabe fehlerhaft
}
// jetzt können Variablenwerte aus dem Datenobjekt in
// Programmvariablen übernommen werden
dX = IpsData.dX;
return TRUE;
}
Der Konstruktor der Klasse ACIpsInstance initialisiert die nötigen Attribute. Mit folgender Methode kann vom Anwendungsprogramm ein Applikationsbuffer an das Interpretersystem übergeben werden.:
UseBuffer(scsDBDBuffer,BufName,lDatei,lUniqueKey,lISN,lLocked)
Legt eine Kopie des Applikationsbuffers im Aktionen-Objekt unter dem Ident BufName an. Über den eindeutigen Pfad kann sichergestellt werden, dass der Satz innerhalb des AS selbst gesperrt werden kann.
Dies ist die einzige Möglichkeit einen Satz, der nur über einen mehrdeutigen Pfad zu finden ist, gesperrt und mit ISN dem Interpretersystem bekannt zu machen.
Der Buffer kann allerdings auch über Anweisungen in der Steuerdatei im IS bekannt gemacht werden, wobei keine Angaben zu ISN und Lockmodus gemacht werden können. Allerdings kann man den Satz noch einmal im IS lesen und kennt danach diese beiden Attribute.
Der Aufruf des Interpretersystems aus der Anwendung ist also sehr einfach, der Aufruf Buchung.Run() führt dazu, dass das IS die Steuerdatei einliest und ausführt.
Cachingmechanismen zum Verbessern der Performance können später implementiert werden. Man könnte z.B. den Text einer bereits eingelesenen Steuerdatei im Memory halten, oder sogar die direkt interpretierbare Form nach dem Syntaxcheck als Vorlage verwenden.
Beispiel Steuerdatei:
//
// Dies ist ein Beispiel einer Kommentarzeile in einer Steuerdatei
//
// Es folgt eine Einbindung einer funktionserweiternden DLL
//
#UseDllExtension=externe.DLL
String(strDispo);
Long(nSteuerung,nUniquePath);
AssignLong(nSteuerung,1);
AssignString(strDispo,“DISPO“);
AssignLong(nUniquePath,4);
BufUseAssocBuffer(strDispo,23,0,23,nUniquePath); // Buffer anziehen
BufLockBuffer(strDispo);
KAZugang(strDispo,nSteuerung);
if ( nSteuerung == 2 )
{
KAZugangZusatz2(strDispo);
}
else
{
ExterneKAZugangZusatzSonst(strDispo);
}
BufUpdateBuffer(strDispo);
Das neue Buchungssystem von INFRA muss dem Interpretersystem seine Funktionalität in Form von Funktionsaufrufen zur Verfügung stellen. Diese Aufrufe entstehen durch mehr oder weniger geschicktes Zerlegen der bisherigen Buchungsvorgänge. Das Ziel ist es ein System von möglichst unabhängigen Funktionen zu erzeugen, die dann in verschiedenen Buchungsarten einsetzbar sind.
Wie geschieht die Einbindung der atomaren Aktionen, wie z.B. KAZugang(nVariable)?
Diese Aktionen werden die unterschiedlichsten Funktionsmerkmale bzgl. Anzahl und Art der Parameter aufweisen. Eine zusätzliche Anforderung kann einen zusätzlichen Parameter mit sich bringen. Eine solche Änderung sollte allerdings nicht eine neue Übersetzung des Aktionensystems zur Folge haben.
Deshalb werden die Aktionen in separaten DLL’s untergebracht werden, die folgende Nebenbedingung erfüllt:
Es existiert eine Funktion QueryInterface innerhalb der DLL, die dem Precompiler eine Liste von Funktionsbeschreibungen plus Anzahl derselben übergibt, die in der DLL zur Verfügung stehen. Außerdem liefert der Aufruf die Adresse einer sogenannten DispatchFunction, die dazu dient, Funktionsaufrufe, die der externen DLL zugeordnet wurden, durchzuführen.
Die Form der Funktionsbeschreibung ist vom IS vorgeschrieben. Sie enthält zu jeder Funktion einen Namen, der in der Steuerdatei zu verwenden ist, plus eine interne ID, die beim Aufruf der DispatchFunction verwendet wird. Weiterhin sind in einer Funktionsbeschreibung Anzahl und Art der Parameter, sowie der Typ (0 oder SIFNCT_VARPAR) der Funktion hinterlegt. Die Struktur einer Funktionsbeschreibung ist in AcSsiScr.hpp zu finden.
Die DispatchFunction hat den folgenden Typ:
|
LONG DispatchFunction(
|
| |
|
|
LONG
|
lID,
|
|
|
ULONG
|
ulApplHandle,
|
|
|
ACIpsData
|
&IpsData,
|
|
|
VOID*
|
II, //vorher ACIpsInstanc &IpsInstance
|
|
|
LONG
|
*plNumPar,
|
|
|
DOUBLE
|
*pdNumPar,
|
|
|
SCString
|
*pscsStrPar);
|
Das IS hat beim Übersetzen der Steuerdatei, DLL und interne FunctionID lID erkannt. Bei der Ausführung der Steuerdatei ruft das IS nun die DispatchFunction. der entsprechenden DLL auf und gibt die interne FunctionID (intern bzgl. der funktionserweiternden DLL) mit.
Die Werte im Datenobjekt IpsData sind über eine Referenz auf dieses Objekt jeder atomaren Aktion zugänglich. Das IpsInstanceobjekt ist in den Funktionen ebenfalls über eine Referenz zugänglich. Dies ist wegen des Zugriffs auf die IS-Buffer notwendig.
DispatchFunction muss die Aufrufparameter der atomaren Aktion aus den Funktionsparameterarrays und dem Aktionsparameter selbst zusammenstellen. Nach der Rückkehr von DispatchFunction() aktualisiert das Aktionensystem die Variablenwerte, die in der gerufenen Funktion als Rückgabeparameter (alle Rückgabeparameter in Aktionen müssen in „REFFUNCTION RefFunctions“ mit „|SIVAR_BYREF“ als solche definiert werden) definiert sind.