\chapter{Ein Generator zur Anbindung externer C++-Bibliotheken}
\label{gdl}

Die objektorientierte
Programmiersprache C++ findet in der industriellen Praxis zunehmende 
Verbreitung. Gegen"uber anderen objektorientierten Sprachen erhofft man sich
durch ihren Einsatz einen sanfteren, allm"ahlicheren "Ubergang in die Benutzung 
objektorientierter
Technologien. Dies liegt unter anderem darin begr"undet, da"s es sich um eine
hybride Sprache handelt, die sowohl einen objektorientierten als auch einen 
imperativen Programmierstil erlaubt. Letzterer wird dadurch erm"oglicht, 
da"s die inzwischen sehr weit verbreitete Sprache C eine echte Teilsprache von 
C++ ist. 

Die Verbreitung von C++ wird insbesondere auch durch die zunehmende Entwicklung 
allgemein verwendbarer Klassenbibliotheken 
vorangetrieben. Dabei wird 
insbesondere die Wiederverwendbarkeit von Code betont, der f"ur viele 
wichtigste Aspekt der Objektorientierung.
Die Benutzung externer (d.h. nicht selbst entwickelter) Bibliotheken wird 
besonders attraktiv durch die M"oglichkeit,
Klassen nach eigenen Anforderungen zu spezialisieren und Methoden zu
"uberschreiben (engl. {\sl overriding}), was ein H"ochstma"s an
software-technischer Flexibilit"at verspricht.
Hinzu kommt, da"s diese Produkte meist von vielen Benutzern mit 
unterschiedlichsten Anforderungen erprobt 
und getestet sind. Diese Aspekte tragen entscheidend zur Effizienz der
Software-Entwicklung bei.
Da externe Bibliotheken zur Grundkonzeption des Tycoon-Systems 
geh"oren \cite{Matt93}
und das Angebot an C++-Klassenbibliotheken st"andig w"achst, liegt es nahe, 
sich auch solche Dienste innerhalb
des sprachlichen Rahmens von \TL\ nutzbar zu machen.
%und damit die M"achtigkeit des Gesamtsystems zu steigern.  

Die zentralen Begriffe dieses Kapitels h"angen wie folgt zusammen:
Ein {\em Gateway} ist die Software-Komponente
eines Systems, die die erforderlichen Bindungen  geh"orend zu
%Lehman hat hier gemeckert
{\em einer} externen Bibliothek (nachfolgend {\em C++-Server} genannt)
 enth"alt. Es besteht im allgemeinen aus
einer Menge modular zusammenh"angender Teil-Gateways. Ein 
{\em generisches Gateway} ist durch {\em Schnittstellenbeschreibungen} 
parametrisierbar und generiert als Instanzen spezialisierte 
(Teil-)Gateways.

In diesem Kapitel wird beschrieben, 
welche Aufgaben und Probleme zu l"osen sind, die sprachlichen Konzepte von
C++ und \TL\ aufeinander abzubilden. Dazu wird eine im Rahmen dieser Arbeit
entwickelte Schnittstellenbeschreibungssprache ({\sl gateway description
language} GDL) benutzt. 
Die Implementierung dieser Schnittstellenbeschreibungssprache 
f"uhrt zu einem generischen Gateway oder einem 
Gateway-Generator, wie er in Kapitel \ref{generator} beschrieben ist.
Den Zusammenhang zwischen den einzelnen Abschnitten dieses und des letzten
Kapitels veranschaulicht Abbildung \ref{gdl-overview}.

\begin{figure}[hbt]
\leavevmode
\def\epsfsize#1#2{0.7\textwidth}
\centerline{\epsfbox{gdl-overview.epsf}}
\caption{\label{gdl-overview} Struktur von Kapitel 3}
\end{figure}


\subsubsection{Anforderungen an generische Gateway-Implementationen}
Ziel ist es, die in C++-Klassenschnittstellen definierten Methoden dem
\TL-Programmierer in transparenter Form zur Verf"ugung zu stellen, d.h.
er soll von der Existenz eines externen C++-Servers abstrahieren und die
externe Bibliothek gem"a"s der \TL-Syntax und -Semantik benutzen k"onnen.
Insbesondere sollen dabei die Vorteile von \TL\ wie statische Typisierung,
Funktionen h"oherer Ordnung und Polymorphismus in Bezug auf den externen 
Diensterbringer erhalten bleiben.

Allgemein: Um eine Sprache $L_{intern}$ durch ein generisches Gateway f"ur eine
Sprache $L_{extern}$ zu erweitern, m"ussen folgende Anforderungen 
erf"ullt werden 
\cite{ScMa93}:
\begin{itemize}
\item Das Typsystem von $L_{intern}$ mu"s m"achtig genug sein, Typen von
Werten aus $L_{extern}$ auszudr"ucken. Dies betrifft sowohl die Basistypen als
auch insbesondere die Typkonstruktoren (\ref{sprachabbildung}).
\item Es mu"s ein Werkzeug geben, da"s die Abbildung von Signaturen aus 
$L_{intern}$ auf Signaturen aus $L_{extern}$ unterst"utzt (\ref{generator}).
\item Es mu"s einen Mechanismus geben, um zur Laufzeit Bindungen an externe 
Objekte, insbesondere Funktionen, zu etablieren (\ref{basismechanismen}). 
\end{itemize}
Nachfolgend wird erl"autert, auf welche Weise die Sprache \TL\ und das im
Rahmen dieser Arbeit entwickelte Gateway-Generierungswerkzeug zur Erf"ullung 
dieser Bedingungen beitragen.



		\section{Schnittstellenbeschreibungen}

Als Grundlage zur Anbindung eines Dienstes ben"otigt man eine Beschreibung
seiner Schnittstellen. Leider erlaubt C++ nicht die konsequente 
Trennung von Schnittstelle und Implementation durch sprachliche Mittel.
Da in den sogenannten C++-Header-Dateien, die per Konvention zur
Beschreibung von Klassenschnittstellen benutzt werden, 
auch Implementationscode vorkommen kann, eignet sich deren Inhalt nicht als 
Eingangsinformation, auf dessen Grundlage man eine Abbildung der Sprachkonzepte
nach \TL\ definieren und anwenden k"onnte. 
Ein pr"aprozessorbasierter Ansatz zur Trennung von Schnittstelle und
Implementation in C++ wird in \cite{Mar91} vorgeschlagen, bei dem die 
notwendigen Programmierkonventionen f"ur den Programmierer explizit sichtbar 
gemacht werden. 
% AGe:  Bezug?
Entsprechend wird auch f"ur diese Arbeit ein Schnittstellenbeschreibungsmittel 
ben"otigt, das die M"oglichkeit bietet, von
Implementierungssaspekten vollst"andig zu abstrahieren sowie f"ur die
Tycoon-Umgebung spezifische Erg"anzungen zuzulassen. Nachfolgend wird deshalb
die C++-Schnittstellenbeschreibungssprache {\bf GDL} ({\sl gateway definition 
language}) eingef"uhrt. Diese hat u.a. folgende wichtige Eigenschaften:
\begin{description}
\item [Deklarativit"at:] GDL ist eine reine Spezifikationssprache ohne 
algorithmische Bestandteile.
\item [Modularit"at:] Schnittstellenbeschreibungen k"onnen andere importieren.
\item [Pragmatik:] Um die Erstellung von GDL-Dateien so
einfach wie m"oglich zu gestalten, wird eine C++-nahe Syntax gew"ahlt, so da"s
C++-{\em Headerfiles} leicht als Grundlage verwendet werden k"onnen. 
\end{description}
Au"serdem ist vorgesehen, da"s sp"atere Versionen der GDL (bzw. des 
Gateway-Generators) die Anbindung weiterer Sprachen unterst"utzen.

Die Benutzung von Schnittstellenbeschreibungssprachen ist weit verbreitet 
im Kontext verteilter, offener, heterogener Umgebungen. Dienste werden dort
"ublicherweise in einer IDL (engl. {\sl interface definition language})
beschrieben, zu der sprachspezifische Abbildungsvorschriften zur
{\em Stub}-Generierung existieren (\cite{OMG91}, \cite{DCE90}, \cite{ILU94}, 
\cite{SUN90}).
Einige dieser IDLs haben den Anspruch, verschiedene
Sprachabbildungen unterst"utzen zu k"onnen (z.B. f"ur C und C++), da in
heterogenen Umgebungen typischerweise verschiedene Sprachen zur
Anwendungsprogrammierung eingesetzt werden. Innerhalb der persistenten
integrierten Programmierumgebung Tycoon ist allerdings nur die Abbildung von 
GDL nach \TL\ von Interesse, da \TL\ nicht nur f"ur alle Datenmodellierungs- und
Applikationsprogrammieraufgaben, sondern auch f"ur den "uberwiegenden
Anteil der Systemprogrammierung benutzt wird.


	\subsection{GDL-Sprachkonzepte}
	\label{sprachkonzepte}

GDL ist die Sprache, die vom C++/\TL-Gateway-Generator akzeptiert wird. Sie ist
vom Typ LL(1) und unterst"utzt eine Untermenge der C++-Syntax bez"uglich der 
Deklaration von Konstanten, Typen und Klassen mit ihren Methoden, 
sowie die C++-Basistypen.
Eine Beschreibung ihrer syntaktischen und lexikalischen Regeln findet sich in 
Anhang \ref{grammar}.  

\subsubsection{GDL-Spezifikation}
Eine GDL-Schnittstellenspezifikation besteht aus dem Kopfteil sowie beliebig
vielen Typ- und
Konstantendeklarationen. Der Kopfteil enth"alt neben der Liste der importierten
Schnittstellenbeschreibungen die Namen der zu generierenden
\TL-Modulimplementation und der \TL-Schnittstelle. Dies ist notwendig, um
Namenskonflikte mit bereits existierenden \TL-Modulen vermeidbar zu machen.
Diese k"onnen entstehen, weil \TL-Bibliotheken keine gekapselten 
Namensr"aume darstellen und somit keine "Uberdeckungen von Modulbezeichnern 
m"oglich sind. Ein Beispiel:
\begin{xple}
\kw{gateway} ''C++'' window :Window
\kw{import} outputDevice resource ...
\end{xple}

Der Import von Schnittstellenbeschreibungen ist unqualifiziert und entspricht 
einer {\bf open}-Anweisung in \TL\ auf
Modulebene. Qualifizierter Import ist derzeit nicht notwendig, da C++ in der
Version 2.3 noch keine Namensr"aume oberhalb von Klassen\footnote{sog. 
{\sl namespaces}, derzeit noch in der Standardisierungsphase}
unterst"utzt.

\subsubsection{Typ- und Konstantendeklarationen}
{\bf Konstanten} werden durch die {\sl define}-Anweisung 
sowie durch den Typkonstruktor {\sl enum} definiert. Ein Beispiel:
\begin{xple}
\label{enum}
\kw{define} BLACK 0
\kw{enum} ClosedDay \{MONDAY, SATURDAY = 5, SUNDAY = 6\}
\end{xple}
Die {\sl define}-Anweisung ist allerdings nicht wie in C Bestandteil des
Pr"aprozessors, sondern in die Sprache integriert.

{\bf Basistypen:} Es stehen grunds"atzlich alle C-Basistypen zur
Verf"ugung ({\sl char, int, float~\dots}), allerdings kommt bei der Abbildung
dieser Typen zum Tragen, da"s \TL\ nicht so ein
reichhaltiges Repertoire an numerischen Typen unterschiedlicher Gr"o"se wie
C++ hat. Details der Abbildung der Basistypen werden in 
Abschnitt~\ref{sprachabbildung} beschrieben.

An {\bf Typkonstruktoren} stehen die Anweisungen {\em typedef} und {\em class}
zur Verf"ugung.
Erstere dient der Vergabe von Bezeichnern f"ur Typen (wie in C++).

{\bf Klassen} aggregieren Operationen und Attribute ({\sl members} 
in C++\-Terminologie) zu einer {\em "offentlichen} Schnittstelle, d.h. es wird 
im Sinne einer strikten Trennung von Schnittstelle und Implementation nicht wie 
in C++ zwischen privaten, gesch"utzten und "offentlichen Bestandteilen
einer Klasse unterschieden.
Die aus Kompatibilit"atsgr"unden zu C auch in C++
eingef"uhrten {\em structs} sind in GDL nicht notwendig, da der einzige
Unterschied zwischen Strukturen und Klassen darin besteht, da"s 
der Sichtbarkeitsbereich ihrer Bestandteile bei Strukturen auf "`"offentlich"',
bei Klassen auf "`privat"' voreingestellt ist.
"Uber die reine Spezifikation hinausgehende
Implementationsdetails wie z.B. Funktionsr"umpfe ({\em inlining}) sind 
ausdr"ucklich nicht zugelassen. GDL-Klassen bilden keinen Namensraum, d.h. da"s
insbesondere Operationen in verschiedenen Klassen innerhalb einer
GDL-Spezifikation eindeutig sein m"ussen. Diese Forderung ergibt sich aus der
Art der gew"ahlten Abbildung von Klassen auf 
von Modulschnittstellen exportierte ADTs (siehe Abschnitt
\ref{sprachabbildung}). Der Regelfall ist, eine Klasse pro 
GDL-Spezifikation zu definieren und nur wechselseitig rekursive 
Klassendefinitionen in einer Spezifikation zusammenzufassen. 
Die Angabe einer oder mehrerer
Oberklassen hat Auswirkungen auf die resultierende \TL-Typhierarchie (siehe
Abschnitt \ref{typabbildung}). Ein Beispiel f"ur eine Klassendefinition:

\begin{xple}
\kw{class} Window=$>$T ''A window is a rectangular outputdevice'' : Outputdevice
\{
 ...
 \kw{virtual void} Paint ''Redraw method'' (\kw{const} \&Rectangle rRect);
 ...
\}
\end{xple}
In Methodendeklarationen werden die in C++ "ublichen 
Parameter"ubergabemechanismen unterst"utzt ({\em by value, pointer, reference}).
Ferner bedeutet das Schl"usselwort {\sl virtual}, da"s Vorkehrungen
getroffen werden, die betreffende Methode mit einer \TL-Funktion durch den 
Programmierer "uberschreibbar zu machen. Ein {\em Callback} durch den externen
Server resultiert dann in einem Aufruf der entsprechenden \TL-Funktion anstelle
der Standardimplementierung dieser Methode, wobei f"ur den Server 
der Unterschied zwischen einer in C++ und einer in \TL\ implementierten 
virtuellen Methode nicht erkennbar ist. N"ahere Erl"auterungen zu diesem 
Mechanismus enth"alt Abschnitt \ref{basismechanismen}.

Durch das Schl"usselwort {\sl static} werden Methoden einer Klasse 
gekennzeichnet, die ohne Nennung eines Objektes dieser Klasse
aufgerufen werden k"onnen. In C++ dient diese Kennzeichnung der Vermeidung 
globaler Funktionen. 

\subsubsection{Bezeichnervergabe und Dokumentation}
Bei der Deklaration k"onnen GDL-Bezeichner optional eine 
Umbenennungskomponente (ausgedr"uckt durch =$>identifier$) enthalten, um
sie bei der {\em Stub}-Generierung an g"angige Programmierkonventionen anpassen 
zu k"onnen, sofern eine automatische Bezeichnervergabe nicht erw"unscht ist.
Optional kann ein GDL-Bezeichner durch eine Zeichenkette zu
Dokumentationszwecken erg"anzt werden. Diese wird dann als Kommentar an 
passender Stelle in der generierten Schnittstelle eingef"ugt.

\subsubsection{Einbeziehung von TL-Standardbibliotheken}
Mitunter enthalten C++-Bibliotheken Definitionen von Standardklassen, f"ur
die "ahnliche Abstraktionen in den \TL-Standardbibliotheken bereits existieren
(z.B. f"ur Standarddatentypen).
Damit nun die gewohnten \TL-ADTs auch in Signaturen von Operationen eines 
externen Dienstes benutzt werden k"onnen, wird dies dem Generator durch 
die {\sl use-}Klausel mitgeteilt, z.B.:
\begin{xple}
\kw{use} T \kw{from} \id{string} \kw{as} \id{String} \kw{using} \id{stringConvert}
(* Verwende den \TL-Typ \id{T} aus dem Modul \id{string} anstelle von \id{String}
   unter Benutzung von Umwandlungsfunktionen, die im Modul
   \id{stringConvert} implementiert sind *)

\kw{class} Window=$>$T : Outputdevice
\{
    ...
    String getText();
    ...
\}
\end{xple}

Zur Generierung der Implementation von {\sl Window::getText()} ben"otigt
der Generator Umwandlungsfunktionen, die C++-Objekte der Klasse 
{\sl String} in \TL-Werte des Typs {\sl string.T} transformieren k"onnen 
(bzw. umgekehrt). Dem Generator wird mitgeteilt, da"s diese durch das 
Modul {\sl stringConvert} implementiert sind. Alle 
Konvertierungsschnittstellen sind konzeptionell Instanzen des 
Typoperators {\sl Convert}:
\begin{xple}
\kw{Let} Convert(A $<:$\kw{Ok}) =
  \kw{Tuple}
     T $<:$\kw{Ok}
     new(:A) :T
     get(:T) :A
  \kw{end},
\end{xple}
z.B. {\sl StringConvert} = {\sl Convert(string.T)}.

In der entsprechenden Funktionssignatur der generierten Schnittstelle f"ur die
Klasse {\sl Window} kann
dann der durch das \TL-Modul {\sl string} exportierte Typ {\sl T} anstelle der 
externen Klasse {\sl String} verwendet werden. 
Die Implementierung der Umwandlungsfunktionen {\sl new} und {\sl get} im Modul 
{\sl stringConvert} mit der Schnittstelle {\sl StringConvert} ist allerdings 
manuell zu leisten, da Wissen "uber die Semantik der einander entsprechenden 
Typen erforderlich ist.


	\subsection{Schnittstellenbeschreibungssprachen im Vergleich}
	\label{idl-comparing}

In verteilten Systemen tritt h"aufig die Anforderung auf, Dienste unabh"angig
von bestimmten Programmiersprachen auf einem abstrakteren Niveau spezifizieren
zu k"onnen. In Tabelle~\ref{idl-table} werden die Konzepte von 
Schnittstellenbeschreibungssprachen verschiedener, zum Teil kommerzieller 
verteilter Systemumgebungen einander gegen"ubergestellt.  

\input{idltable}

Auff"allig ist bei den meisten dieser Sprachen eine konzeptionelle N"ahe
zu einer bestimmten imperativen oder objektorientierten Programmiersprache 
wie z.B. C (DCE-IDL \cite{DCE90}), C++ (Corba-IDL \cite{OMG91}) oder Modula-3 
(ILU \cite{ILU94}). Dies erleichtert sicher die
Abbildung auf eine favorisierte (oder f"ur wichtig befundene) 
Implementierungssprache, zeigt aber andererseits, da"s die genannten Sprachen 
zur Beschreibung der "offentlichen Schnittstelle verteilter Objekte bzw.
Dienste nicht ausreichen.

Bei der Benutzung der Schnittstellenbeschreibungen dieser Systeme mu"s der 
Programmierer die jeweiligen Sprachabbildungsvorschriften kennen und anwenden.
Die GDL des Tycoon-Systems dient hingegen nicht als Schnittstellenbeschreibung
f"ur den Anwendungsprogrammierer, sondern als reines Hilfsmittel zur Generierung 
von \TL-Schnittstellen. F"ur den Anwendungsprogrammierer hat dies den Vorteil, 
da"s er von der Existenz dieser Beschreibungssprache und der 
Abbildungsvorschriften nach \TL\ abstrahieren und nur mit Hilfe der 
generierten \TL-Schnittstellen programmieren kann.

Aufbauend auf den Erfahrungen mit der Abbildung von GDL-Strukturen auf \TL\
ist es Gegenstand weiterer Arbeiten im Tycoon-Projekt, 
Vorschriften f"ur eine Abbildung einer der standardisierten IDLs 
in \TL-Typstrukturen zu spezifizieren. Im Rahmen einer vom Autor durchgef"uhrten
Studie ist dies f"ur die IDL der OMG vollst"andig gelungen.
Dadurch ist es m"oglich, mit Hilfe des
\TL-Typ"uberpr"ufers die Schnittstellen unabh"angig voneinander
entwickelter externer Dienste, die also nicht in einer expliziten
Vererbungsbeziehung zueinander stehen, auf Kompatibilit"at hin zu
"uberpr"ufen. In einem offenen Markt von Diensten k"onnte man dann z.B. 
anhand der Abbildungsregeln  "uberpr"ufen, ob ein bestimmter angebotener Dienst 
einer in \TL\ beschriebenen Referenz-Schnittstelle gen"ugt. 
Diese Typkomponente eines solchen {\em Traders} \cite{MJML95b} 
w"are auch ein Anwendungsfeld f"ur {\em dynamische Typen} (siehe Abschnitt
\ref{dynamicTypes}), da Typrepr"asentationen aus verschiedenen Kontexten
miteinander verglichen werden m"ussen.


		\section{Spezifikation der GDL/TL-Sprachabbildung}
		\label{sprachabbildung}

In diesem Kapitel wird die Abbildung der GDL-Konzepte auf \TL\ definiert, d.h.
es wird beschrieben, wie in \TL\ die GDL-Basistypen, konstruierte Typen und 
Konstanten sowie Klassenoperationen so ausgedr"uckt werden, da"s die 
Vorz"uge des C++-Typsystems bewahrt bleiben.

Eine Kompilationseinheit der GDL (genannt {\em gateway}) wird  in 
genau ein \TL-Schnitt\-stellenmodul und ein \TL-Implementationsmodul 
mit den in der Kopfzeile
des {\em gateways} angegebenen Namen "ubersetzt, wobei in der \TL-Schnittstelle 
die Signaturen aller im {\em gateway} definierten Typen und Konstanten 
exportiert werden.

In Tabelle \ref{konzepte-tabelle} werden die einander entsprechenden 
Sprachkonzepte von GDL und \TL\ im "Uberblick dargestellt und in den folgenden
Abschnitten auf Einzelheiten der gew"ahlten Abbildung eingegangen.
\begin{table}[h] 
\label{konzepte-tabelle}
\begin{tabular}{|l|l|}
\hline
\rule[-3mm]{0mm}{8mm}
{\bf GDL} & {\bf TL}\\
\hline
Gateway & Modul\\
Konstante ({\sl define}) & Wertbindung \\
Konstante ({\sl enum}) & Export von Werten eines semi-abstrakten Typs ($<:$Int) \\
{\sl class} & ADT mit Konstruktor- und Destruktorfunktion, \\
& Lese- und Schreibfunktionen f"ur Attribute \\
{\sl typedef} & Typbindung \\
Klassenmethoden & Funktionen eines ADT \\
Subtyppolymorphismus durch & Subtyppolymorphismus durch \\
Vererbung & einschr"ankende Typbindungen \\
\hline
\end{tabular}
\caption{Gegen"uberstellung der Sprachkonzepte}
\end{table}
Vorweg sei gesagt, da"s die in Abschnitt \ref{programmierstile} beschriebene 
exemplarorientierte Modellierung von
Objekttypen bei tiefgeschachtelten Vererbungshierarchien zu hohem
Speicheraufwand f"uhrt. Die versuchsweise Realisierung der Anbindung der
GUI-Klassenbibliothek {\sf StarView}$^{TM}$\footnote{siehe Kapitel \ref{gui}} 
in diesem Stil erforderte au"serdem einen 
sehr hohen Typ"uberpr"ufungsaufwand bei der "Ubersetzung der generierten Module, 
bedingt durch die gro"se Zahl erforderlicher {\em Repeat}-Anweisungen und dadurch
h"aufiger Subtyptests. Zur Anbindung klassenorientierter Bibliotheken ist 
die exemplarorientierte Modellierung von Objekttypen demzufolge nicht geeignet, 
da Sprachmittel zur Klassifikation von Objekten fehlen.
Daher stellt sich die Abbildung objektorientierter Konzepte von C++
auf den modularen Stil unter Verwendung semi-abstrakter Datentypen als die 
bessere weil effizientere Alternative dar. 
Wie sich im folgenden herausstellt, wird dabei die urspr"ungliche 
Ausdrucksm"achtigkeit von C++ nicht wesentlich eingeschr"ankt.


	\subsection{Abbildung der Typsysteme}
	\label{typabbildung}

In diesem Abschnitt wird die Abbildung des Typsystems von GDL, d.h. C++, auf \TL\
bez"uglich Basistypen, Konstanten und Klassen erl"autert.

\subsubsection{Basistypen}
Die Abbildung der GDL-Basistypen auf \TL\ orientiert sich an den Erfordernissen
der bidirektionalen C-Schnittstelle \cite{MMM93}. Problematisch ist jedoch die
Anbindung von Funktionen, in deren Signatur Zeiger vom Typ {\em void}
vorkommen, das hei"st Zeiger auf beliebige Objekte. Diese Objekte k"onnen
dann zwar mangels Typinformation von C aus nicht manipuliert, wohl
aber z.B. in Datenstrukturen verwaltet oder einfach weitergereicht werden.
Die korrekte Behandlung externer Referenzen auf \TL-Datenstrukturen wird in
Abschnitt \ref{externeReferenzen} beschrieben.
% AG: soll das dafuer die Loesung sein?

\subsubsection{Konstanten}
% AG: tabellarisch besser
{\sl Define}-Anweisungen werden in entsprechende Bindungen "ubersetzt:
\begin{xple} 
\kw{define} BLACK 0    $\longrightarrow$ \kw{let} black = 0
\end{xple} 
wobei der tats"achliche Wert der Konstante im Implementationsmodul verborgen
ist und in der Schnittstelle die Signatur
\begin{xple} 
black :\kw{Int}
\end{xple} 
exportiert wird.
Die {\sl enum}-Anweisung im Beispiel auf Seite \pageref{enum} erzeugt 
entsprechende Bindungen, wobei folgende Signaturen exportiert werden:
\begin{xple} 
ClosedDay $<$:\kw{Int} 
monday, saturday, sunday :ClosedDay
\end{xple} 
Ein Vorteil dieser Abbildung ist, da"s Werte vom Typ {\sl
ClosedDay} an allen Stellen verwendbar sind, an denen Werte vom Typ {\sl Int}
verlangt werden, jedoch umgekehrt Funktionen, in deren Signaturen der Typ 
{\sl ClosedDay} vorkommt, gegen falsche Verwendung gesch"utzt sind. Letzteres
ist in C nicht der Fall, denn man k"onnte statt eines g"ultigen Wochentages
auch beliebige andere ganzzahlige Werte "ubergeben.

\subsubsection{Klassen}
Die in Abschnitt \ref{programmierstile} gef"uhrte Diskussion ergab, da"s der
objektbasierte, exemplarorientierte Programmierstil weniger geeignet
zur Modellierung gro"ser klassenbasierter Programmsysteme ist.
Daher wird eine GDL-Klasse mit ihren Methoden auf eine Menge von
Funktionen auf einem abstrakten Datentyp, dem Typ der
Objekte dieser Klasse, abgebildet. Diese Funktionen werden zusammen mit dem 
abstrakten Typ im Rahmen einer Modulschnittstelle exportiert.
Aus einer GDL-Schnittstellenbeschreibung mit
mehreren Klassen entsteht eine \TL-Schnittstelle mit entsprechend
vielen abstrakten Datentypen.
F"ur Klassenkomponenten, die keine Funktionen
sind (also "offentlich sichtbare Attribute), wird je eine Lese- und
Schreibfunktion erzeugt. Dadurch werden GDL-Klassen, die einen semi-abstrakten
Datentyp repr"asentieren, in einen vollst"andig abstrakten Datentyp
"uberf"uhrt. Man erh"alt so auch immer den aktuellen Wert des Attributes, was 
bei einer statischen Bindung an einen Wert nicht der Fall ist.

Die Klassenhierarchie der externen Bibliothek wird in \TL\ dadurch nachgebildet,
da"s die aus den GDL-Klassenspezifikationen resultierenden ADTs in eine
Subtypbeziehung zueinander gebracht werden, die der urspr"unglichen 
Vererbungshierarchie entspricht. Da in \TL\ das Subsumptionsprinzip
gilt (siehe Abschnitt \ref{typkonzepte}), k"onnen Funktionen eines aus einer 
Klassenspezifikation resultierenden 
ADTs auch auf Instanzen eines Subtyps dieses
Typs angewandt werden ({\em Subtyppolymorphismus}).
Bei Mehrfachvererbung sind allerdings Umwandlungsfunktionen
zu generieren, da im Typsystem von \TL\ Typbindungen nur {\em einer} 
Einschr"ankung gehorchen k"onnen (siehe Beispiel auf Seite \pageref{mi-bsp}
unten). 
Die Typumwandlung mu"s dabei vom C++-Compiler vorgenommen werden,
da nur er das tats"achliche Speicher-Layout von Objekten kennt.

Als Beispiel sei die Klasse {\sl Preview}, Subklasse von {\sl Window}
und {\sl Printer}, aufgef"uhrt:  
\begin{xple}
\kw{gateway} ''C++'' preview :Preview
\kw{import} window printer fraction
\kw{export}
   \kw{class} Preview : Window, Printer \{
       \kw{constructor} Preview=$>$new(Window* parent)
       Fraction changeZoomFactor(const Fraction\& factor)
       ...
   \}
\kw{end}
\end{xple}

Die resultierende \TL-Schnittstelle sieht wie folgt aus:
\begin{xple}
\begin{tabbing}
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\= xxxxxx \= \kill
  \kw{interface} Preview \\
  \kw{import} window printer fraction optional ... \\
  \kw{export}  \\
    T $<$:window.T \>(* T ist Subtyp der erstgenannten Superklasse *) \\
    new(parent :optional.T(window.T)) :T \>(* Konstruktor *) \\
    changeZoomFactor(self :T  factor :fraction.T) :fraction.T \\
    ...                      \>(* weitere Methoden der Klasse Preview *) \\
    asPrinter(:T) :printer.T \>(* in C++ implementierte Typkonvertierung *)\\\
  \kw{end} \\
\end{tabbing}
\end{xple}

	\subsection{Abbildung weiterer Sprachkonzepte}

\subsubsection{Methoden und Overriding}
\label{overriding-abbildung}
Parameter"ubergaben an \TL-Funktionen haben grunds"atzlich Referenzsemantik,
d.h. es werden keine Kopien der Aktualparameter erzeugt. In den Signaturen
von \TL-Funktionen ist daher nicht mehr ersichtlich, ob an den C++-Server
Objekte oder Objektreferenzen "ubergeben werden. Die jeweils korrekte 
"Ubergabeform wird in der Implementation der Abbildung von GDL nach C gew"ahlt
(siehe Beispiele f"ur {\em Wrapper}-Funktionen auf Seite \pageref{wrappers}).

Zeiger werden auf
den durch das \TL\ Standardmodul {\sl optional} exportierten Typoperator {\sl T}
abgebildet (siehe obiges Beispiel). Dieser Datentyp zur Modellierung optionaler
Werte hat folgende Definition:
\begin{xple}
\kw{Oper}(A $<:$\kw{Ok}) $<:$\kw{Ok} 
   \kw{Tuple}
      \kw{case} nil
      \kw{case} notNil \kw{with} value :A
   \kw{end}
\end{xple}
Er wird in dem Sinne verwendet, da"s ein nullwertiger Zeiger in C der Option
{\sl nil} entspricht. Der Vorteil dieser Modellierung ist, da"s der in 
C-Programmen h"aufig auftauchende Fehler der Dereferenzierung eines 
nullwertigen Zeigers in \TL\ nicht auftreten kann.

Funktionen eines ADT erhalten als ersten Parameter immer eine
Variable dieses Typs, da sie ja nicht 
(wie beim objektorientierten Ansatz) 
auf einen gekapselten Objektzustand zugreifen k"onnen (vgl. Abschnitt 
\ref{datenkapselung}). Eine Ausnahme hiervon bilden Methoden, die in der
GDL-Spezifikation mit dem Schl"usselwort {\sl static} gekennzeichnet sind.
Da diese Methoden unabh"angig von einem bestimmten Objekt aufgerufen werden
k"onnen, braucht hier keine Variable des ADTs als erster Parameter "ubergeben zu 
werden.
Die Signaturen der Konstruktoren eines ADTs entsprechen den 
Signaturen der Konstruktoren der zugrundeliegenden Klasse.

Subklassenbildung in C++ ist h"aufig mit der (signaturerhaltenden)
Redefinition von virtuellen Methoden verbunden, dem sogenannten 
{\sl overriding}.
Wird ein aus einer GDL-Klassenspezifikation resultierender ADT 
vom \TL-Programmierer in der Absicht benutzt, ihn zu spezialisieren,
so mu"s dem externen C++-Server die M"oglichkeit gegeben werden, 
\TL-Funktionen aufzurufen. Dazu wird jede virtuelle Methode als
Attribut eines ADTs betrachtet, f"ur das ein Paar von Schreib-/Lesefunktionen
generiert wird. Beispiel:
\begin{xple}
\begin{samepage}
\kw{interface} Window
\kw{import} rectangle ...
\kw{export}
   ...
   setPaint(:T :\kw{Fun}(:rectangle.T) :\kw{Ok}) :\kw{Ok}
   getPaint(:T) :\kw{Fun}(:rectangle.T) :\kw{Ok}
\kw{end}
\end{samepage}
\end{xple}
Overriding bedeutet dann, dieses Attribut destruktiv zu
"andern (im Beispiel durch einen Aufruf der Funktion {\sl setPaint}). 
Im Gegensatz zu C++ ist dann ein "`Overriding"' auf Objektebene 
m"oglich statt nur auf Klassenebene, so da"s sich verschiedene Instanzen eines 
ADTs dem Server gegen"uber unterschiedlich verhalten k"onnen, wenn ihre
funktionswertigen Attribute unterschiedliche Werte aufweisen. Allerdings 
entsteht durch dieses Vorgehen auch ein erh"ohter Platzbedarf (siehe 
\ref{overriding-emulation}).

\subsubsection{Templates}
Neuere C++-Versionen erm"oglichen die Definition parametrisierter Typen
(Typoperatoren) durch {\em templates}. C++-Templates sind Typoperatoren
erster Stufe, wobei als Typparameter nur Klassen erlaubt sind. Dieses wenig
orthogonale Konstrukt l"a"st sich leicht auf einfache \TL-Typoperatoren abbilden, 
d.h. auf nichtrekursive Typoperatoren erster Stufe. Beispiel:
\begin{xple}
\begin{tabbing}
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\= \kill
    {\bf C++} \>   {\bf TL} \\[0.7cm]
  \kw{template}$<$\kw{class} T$>$ \kw{class} List \{ \>\kw{Tuple} \\
  \kw{public}: \>  List $<:$\kw{Oper}(T $<:$\kw{Ok}) \kw{Ok} \\
    List(); \>  new(T $<:$\kw{Ok}) :T(E) \\
    List\& cons(T elem);\>  cons(T $<:$\kw{Ok}  elem :T  l :List(T)) :List(T) \\
    T\& head();\>  head(T $<:$\kw{Ok}  l :List(T)) :T \\
    List\& tail();\>  tail(T $<:$\kw{Ok}  l :List(T)) :List(T) \\
  \} \>\kw{end} \\
\end{tabbing}
\end{xple}
Hauptanwendungsfall f"ur den Template-Mechanismus ist die Definition
generischer Container-Klassen. Da dessen Definition durch die M"achtigkeit der
\TL-Typoperatoren eine der Hauptst"arken von Tycoon ist, erscheint es nicht als
lohnenswert, "ahnliche Dienste externer Anbieter anzubinden. Au"serdem werden
Templates noch nicht von allen C++-Compilern unterst"utzt. 
Aus den genannten Gr"unden werden Templates vorerst nicht in die Definition 
der GDL aufgenommen. Sollte in Zukunft doch verst"arkt der Wunsch nach
Einbindung von C++-Templates in \TL\ aufkommen, aus welchem Grund auch immer, 
ist eine entsprechende Erweiterung der GDL jederzeit m"oglich, da die Abbildung
bereits definiert ist.
  
\subsubsection{In TL nicht direkt abbildbare C++-Konzepte}
Einige C++-Sprachkonzepte gestatten eine komfortablere Notation gewisser
Programmiersituationen. Zu diesen Konzepten geh"oren:
\begin{itemize}
\item variabel lange Parameterlisten,
\item vorbelegte Argumente,
\item "uberladen von Funktionen und Operatoren, d.h. die M"oglichkeit,
mehrere Funktionen und Operatoren gleichen Namens aber unterschiedlicher 
Signatur zu definieren.
\end{itemize}
Zur Begrenzung der Sprachkomplexit"at von \TL\ wurde auf solche Konzepte 
verzichtet \cite{Matt93}.
Da \TL-Funktionen nur {\em eine} eindeutige Signatur besitzen k"onnen, ist
eine "uberladene Funktion durch eine Menge von \TL-Funktionen abzubilden.
Die Gr"o"se dieser Menge entspricht der Anzahl der m"oglichen Signaturen f"ur
diese "uberladene Funktion. Operatoren sind entsprechend auf \TL-Funktionen 
abzubilden.

	\subsection{Benennungsschema}
	\label{benennungsschema}

Die Abbildung von GDL-Bezeichnern auf \TL-Bezeichner gehorcht folgenden Regeln:
\begin{itemize}
\item Falls vorhanden, wird der nach dem Umbenennungsoperator ($=>$)
angegebene Bezeichner verwendet.
\item \TL-Konventionen f"ur Gro"s-/Kleinschreibung von Bezeichnern werden 
vom Generator automatisch ber"ucksichtigt.
\item GDL-Bezeichner, deren Abbildung zu einem \TL-Schl"usselwort f"uhren
w"urde, sind umzubenennen.
\item Parameterbezeichner einer Funktion d"urfen nachfolgende Modulbezeichner
in der Signatur dieser Funktion nicht "uberdecken wie in folgendem Fall:
\begin{xple}
\kw{import} color
changeColor(color :color.T) :color.T
\end{xple}
Der Parameter {\sl color} mu"s umbenannt werden.
\end{itemize}


		\section{Implementierung der GDL/TL-Sprachabbildung}
		\label{generator}

Die in den vorigen Abschnitten behandelten Abbildungsregeln erlauben eine 
fast vollst"andig
automatisierbare Erzeugung von \TL-Schnittstellen und -Modulen sowie des
erforderlichen C++-Codes (bestehend aus C-{\em Wrapper}-Funktionen und 
abgeleiteten Klassen) aus Spezifikationen in GDL. Die Gr"o"se mancher 
Bibliotheken macht ein solches Vorgehen auch
zwingend erforderlich, da eine manuelle Codierung durch ihren schematischen,
repetitiven Charakter ziemlich fehlertr"achtig w"are.

An die Implementation eines generischen Gateways werden folgende Anforderungen
gestellt:
\begin{itemize}
\item Die Gr"o"se des generierten Gateway-Codes sollte sich in einem 
akzeptablen Rahmen bewegen. 
\item Es sollte keine signifikante Erh"ohung der Laufzeit entstehen. 
\item Generierter Gateway-Code sollte modular aufgebaut sein.
\end{itemize}

	\subsection{Basismechanismen}
	\label{basismechanismen}

In \TL\ stehen die Modularisierungsmechanismen Modul, Modulschnittstelle und 
Bibliothek zur Verf"ugung. Diese unterst"utzen 
die Entwicklung und Wartung gro"ser
Softwaresysteme und erleichtern die Interaktion mit externen
Diensterbringern \cite{Matt93}. Das Modulkonzept 
spielt eine wichtige Rolle als Abstraktionsmechanismus zur
Schnittstellenbeschreibung von abstrakten Datentypen, 
auf den das C++-Klassenkonzept abgebildet wird. Im folgenden werden die
Basismechanismen zur Bindung an externe Funktionen und zur Behandlung von
externen sowie schwachen Referenzen erl"autert.


\subsubsection{Bindung an externe Funktionen}

Die Bindung an externe Funktionen (in Maschinencode) wird 
im Tycoon-System durch die
bidirektionale Schnittstelle zwischen \TL\ und C verwirklicht \cite{MMM93}.
Zu dieser Schnittstelle geh"oren die in der initialen Umgebung vordefinierte
Funktion {\sl bind} sowie das Bibliotheksmodul {\sl cCallback}. Der
Aspekt der Bidirektionalit"at ist besonders im Kontext der Anbindung externer
GUI-Dienste wichtig, da bei diesen s"amtliche Reaktionen des Systems auf
Benutzerinteraktionen durch {\em Callbacks} verwirklicht werden.

Zur Integration externer Funktionen in \TL\ dient die vordefinierte
Funktion {\em bind} mit folgender Signatur:
\begin{xple}
  bind(Function $<:$\kw{Ok}  library, label, format :String) :Function
\end{xple}
Der erste Parameter beschreibt den Typ der aus dem Aufruf resultierenden
\TL-Funktion. Die beiden folgenden String-Literale definieren eine eindeutige
symbolische Adresse, unter der der Maschinencode der externen Funktion zu
finden ist. Als letztes folgt eine Codierung der formalen Parameter und des
R"uckgabewertes, wobei nur die unstrukturierten \TL-Basistypen erlaubt sind.
Komplexere Bindungsanforderung wie z.B. die "Ubergabe strukturierter Werte
m"ussen auf eine mehrfache Anwendung dieser Basisprimitive abgebildet
werden. Details zur bidirektionalen C-Schnittstelle finden sich in \cite{MMM93}.

Eine "ahnliche bidirektionale Schnittstelle k"onnte man sich auch zwischen 
\TL\ und C++ vorstellen, allerdings liegt durch die Kompatibilit"at von C++ zu C 
ein Ansatz nahe, der auf einer Abbildung von C++-Sprachkonzepten auf 
C beruht. Dies hat folgende Vorteile:
\begin{enumerate}
\item Portabilit"at: C++-Compiler codieren Typinformation "uber Parameter
und Klassenzugeh"origkeit in die Namen von Methoden hinein ({\em function
name encoding} oder auch {\em name mangling}), um typsicheres Binden und
{\em Overloading} von Funktionsnamen zu implementieren. Ein Codierungsschema 
hierf"ur wird in \cite{ARM90} beschrieben, es wird allerdings ausdr"ucklich auf 
Implementationsabh"angigkeiten hingewiesen. Ein \TL/C++-Gateway, das Annahmen 
"uber ein bestimmtes Codierungsschema macht, ist deshalb im allgemeinen nicht 
portabel.
%## method dispatch is compiler dependent
\item Einfachheit: Diese wird durch Nutzung vorhander Bindungsmechanismen
erreicht.
\item Wartbarkeit: Da C++ noch im Proze"s der Standardisierung begriffen ist,
ist ein auf standardisierten Konzepten (ANSI-C) basierendes Gateway 
leichter zu warten.
\end{enumerate}

\subsubsection{Callbacks}

Da, wie oben erw"ahnt, GUI-Applikationen in hohem Ma"se auf {\em Callbacks}
basieren, ist ein Mechanismus notwendig, der \TL-Funktionen von externen
Diensterbringern aus aufrufbar macht. Dieser Mechanismus wird durch das 
Bibliotheksmodul {\em cCallback} implementiert. Durch den Konstruktor
{\em cCallback.new} werden \TL-Funktionen derart verpackt, da"s sie
f"ur den externen Diensterbringer als C-Funktionszeiger erscheinen und damit
wie normale C-Funktionen aufgerufen werden k"onnen.

Abbildung \ref{callback} verdeutlicht den {\em Callback-}Mechanismus anhand 
eines typischen Aufrufszenarios einer GUI-Anwendung.
\begin{figure}[hbt]
\leavevmode
\def\epsfsize#1#2{0.9\textwidth}
\centerline{\epsffile{callback.epsf}}
\caption{\label{callback} Callbacks in \TL}
\end{figure}
Aus der Funktion {\sl clickHandler(b :button.T) :{\bf Ok}} wird mittels der 
Callback-Generierungsfunktion {\sl cCalback.new} ein Callback-Objekt erzeugt.
Die C-Funktion {\sl testClickHdl}, die "uber einen Aufruf von {\sl bind} auch
als \TL-Funktion zur Verf"ugung steht, bekommt dieses Callback-Objekt als
Argument "ubergeben. In dieser C-Funktion erscheint das
Callback-Objekt als C-Funktionszeiger und kann als solcher aufgerufen werden.
Der Ablauf eines Aufrufs des \TL-Pendant von {\sl testClickHdl} ist in Abbildung
\ref{callback} grafisch dargestellt. Dabei wird insbesondere der Wechsel
zwischen den beteiligten Sprachebenen deutlich.


\subsubsection{Externe Referenzen}
\label{externeReferenzen}

Grunds"atzlich erm"oglicht
die C-Schnittstelle die "Ubergabe von Referenzen auf \TL-Objekte. Allerdings ist
nicht garantiert, da"s diese ihre G"ultigkeit behalten, da zu jedem beliebigen
Zeitpunkt die automatische Freispeicherverwaltung in Aktion treten kann 
({\em garbage collection}), wodurch sich, implementationsbedingt,
die Referenzen im gesamten Tycoon-Objektgraphen "andern k"onnen.
Durch eine zus"atzliche Indirektion kann man jedoch verhindern, da"s dadurch 
externe Referenzen auf \TL-Datenstrukturen ung"ultig werden.
Dazu werden alle \TL-Objekte, von denen eine Objektspeicherreferenz an C
"ubergeben werden soll, in einer Tabelle verwaltet, deren Lebensdauer
mindestens so gro"s ist wie die des Anwendungsprogramms. "Ubergibt man dann
Referenzen auf Eintr"age in diese Tabelle an C, so ist man sicher, da"s
diese zur Laufzeit der Anwendung ihre G"ultigkeit behalten.


\subsubsection{Schwache Referenzen}

Die meisten \TL-Programme "uberlassen der automatischen Freispeicherverwaltung
die R"uckgewinnung des von ihnen nicht mehr
referenzierbaren
Speichers. Liegen diese Speicherbereiche allerdings in anderen Adre"sr"aumen 
als dem \TL-Objektspeicher, z.B. auf der C++-Halde, so ist ein zus"atzlicher
Laufzeitmechanismus erforderlich, der f"ur die Freigabe solcher
Speicherbereiche verantwortlich ist. Dieser Mechanismus k"onnte durch {\em
schwache Referenzen} implementiert werden, wie sie z.B. f"ur die 
Laufzeitbibliothek von Modula-3 in \cite{M3Bibs} vorgeschlagen werden 
(Schnittstelle {\sl WeakRef}).


	\subsection{{\em Wrapper}-Funktionen}

C++-Compiler erlauben es, Funktionen im C-Stil zu binden, also
ohne die Codierung von Typ\-information in Funktionsnamen. Dadurch lassen sich
C++-Methoden von C-Pro\-grammen aus aufrufen. Dies bietet die M"oglichkeit, die
Implementation einer GDL-Spezifikation in folgender Weise zu
realisieren:
\begin{itemize}
\item Methodenaufrufe werden in C-Funktionen eingeh"ullt.
\item Die "ubersetzten C-Funktionen werden dynamisch zum Tycoon-Laufzeitsystem
hinzugebunden.
\item In den generierten \TL-Modulimplementationen werden C-Funktionen 
mittels der {\sl bind}-Primitive an \TL-Funktionen gebunden. 
\end{itemize}
Beispiele f"ur {\em Wrapper}-Funktionen:
\begin{xple}
\label{wrappers}
/* in GDL:  void Window::SetText(\kw{const} String\& rStr) */
\kw{extern} ''C'' void window\_SetText(Window* self, String* str) {
    \kw{self}-$>$SetText(*str)
}
/* in GDL: \kw{static} Size\& System::GetScreenSizePixel() */
\kw{extern} ''C'' Size* system\_GetScreenSizePixel() {
    return \&System::GetScreenSizePixel()
}
\end{xple}
Bei der Generierung der {\em Wrapper}-Funktionen sind die verschiedenen 
Parameter"ubergabe- und Wertr"uckgabemechanismen von C++ zu ber"ucksichtigen. 
In C existiert
die M"oglichkeit der "Ubergabe oder R"uckgabe von Referenzen nicht, 
stattdessen m"ussen
Zeiger als Argumente "ubergeben oder als Wert zur"uckgegeben werden. 
Verlangt die eingeh"ullte C++-Methode
eine Referenz als Argument, so ist der betreffende Zeiger zun"achst zu
dereferenzieren, bevor er der Methode "ubergeben wird (im Beispiel betrifft
dies das Argument {\sl str}). 
Gibt sie eine Referenz zur"uck, so ist die Adresse des
betreffenden Objektes zur"uckzugeben.

	\subsection{Emulation von Overriding}
	\label{overriding-emulation}

Wie in Abschnitt \ref{overriding-abbildung} behandelt, werden virtuelle
Methoden als Attribut einer Klasse aufgefa"st, f"ur das ein Paar von 
Schreib-/Lesefunktionen erzeugt wird. Die Implementation dieser Funktionen
bedient sich einer Tabelle, deren Eintr"age jeweils ein Objekt mit einem
Methodennamen und einem Callback assoziieren. 
Von jeder Klasse, die virtuelle Methoden exportiert, wird eine Subklasse
generiert, wobei jede dieser Methoden auf folgende Weise "uberschrieben wird:
\begin{itemize}
\item Aus der Callback-Tabelle wird "uber den Objektzeiger
und den Methodennamen auf den vom Benutzer der Bibliothek installierten Callback
(C-Funktionszeiger) zugegriffen und dieser, sofern vorhanden, ausgef"uhrt.
\item Ist kein Callback installiert, so wird die entsprechende Methode der
Superklasse aufgerufen.
\end{itemize}
Vom externen Server get"atigte Aufrufe virtueller Methoden l"osen dadurch
indirekt Aufrufe von \TL-Funktionen aus. Abbildung \ref{overriding}
veranschaulicht diesen Mechanismus.
\begin{figure}[hbt]
\leavevmode
\def\epsfsize#1#2{0.8\textwidth}
\centerline{\epsffile{overriding.epsf}}
\caption{\label{overriding} Emulation von Overriding}
\end{figure}

\subsubsection{Probleme durch Mehrfachvererbung}
Besitzt eine mit virtuellen Methoden ausgestattete Klasse weitere Subklassen, 
so kann man in C++ auch in abgeleiteten Klassen dieser Subklassen Methoden der 
Oberklasse "uberschreiben.
Praktisch bedeutet dies, da"s nicht nur von jeder Klasse, die virtuelle
Methoden besitzt, eine von ihr abgeleitete Klasse generiert werden mu"s,
sondern auch von allen ihren Subklassen, da man ja auch in diesen Methoden
"uberschreiben k"onnen m"ochte (Abbildung \ref{no-multiple-inheritance}). 
\begin{figure}[hbt]
\leavevmode
\def\epsfsize#1#2{0.7\textwidth}
\centerline{\epsffile{no-multiple-inheritance.epsf}}
\caption{\label{no-multiple-inheritance} Overriding ohne Mehrfachvererbung}
\end{figure}
Diese Vorgehensweise f"uhrt allerdings bei tiefen
Klassenhierarchien, bei denen schon auf oberster Ebene viele virtuelle Methoden
vorkommen, die potentiell in vielen anderen Subklassen "uberschrieben werden 
k"onnen, zu umfangreichem Objekt-Code.

W"unschenswert w"are, wenn der Generator den Code f"ur virtuelle Methoden nicht 
in jeder Subklasse neu erzeugen m"u"ste, sondern stattdessen von der
M"oglichkeit der Mehrfachvererbung Gebrauch machen k"onnte, wie in Abbildung
\ref{multiple-inheritance} dargestellt.
\begin{figure}[hbt]
\leavevmode
\def\epsfsize#1#2{0.7\textwidth}
\centerline{\epsffile{multiple-inheritance.epsf}}
\caption{\label{multiple-inheritance} Overriding mit Mehrfachvererbung}
\end{figure}
Dies ist allerdings nicht m"oglich, da in C++ im Falle von Mehrfachvererbung 
der Wert eines Objektzeigers durch implizite oder explizite Typkonvertierung
({\em casting})
ver"andert wird\footnote{
''{\em With multiple inheritance, casting may change the value of a pointer.}''
\cite{ARM90}, S. 221}. Diese Umrechnung kann nur vom C++-Compiler selbst 
vorgenommen werden, da nur er das konkrete Speicher-Layout von Objekten kennt. 

Da allerdings der Aufruf von C++-Methoden von \TL\ aus "uber 
C-{\em Wrapper}-Funktionen geschieht, ist aus Sicht des C++-Compilers keine
Notwendigkeit zur Umrechnung gegeben. Es kann also passieren, da"s eine 
C++-Methode ein anderes Speicher-Layout eines Objektes
erwartet als tats"achlich vorhanden ist, d.h. in C++ gilt in diesem Fall das
Subsumptionsprinzip nicht.
Diese Situation ist beispielhaft in Abbildung \ref{mi-crash} dargestellt. 

\begin{figure}[hbt]
\leavevmode
\def\epsfsize#1#2{0.8\textwidth}
\centerline{\epsffile{mi-crash.epsf}}
\caption{\label{mi-crash} Falscher Zugriff auf Instanzvariablen bei
Mehrfachvererbung}
\end{figure}

Eine Methode, implementiert in Klasse B, kann, angewandt auf ein Objekt der 
Klasse C, zu einem falschen Zugriff auf Instanzvariablen des Objektes f"uhren,
wenn nicht vorher der Betrag $delta(B)$ zum Objektzeiger addiert wird.


	\subsection{Architektur und Implementierung}

Der Gateway-Generator ist in \TL\ unter Nutzung folgender generischer
Tycoon-Dienste implementiert worden:
\begin{itemize}
\item Tycoon-Compiler-Toolkit \cite{SchMa92}: Parser-Generator auf Basis von
LL(1)-Grammatiken, 
\item Generische {\em Unparser}-Schnittstelle zur Generierung formatierter 
Texte,
\item Bulktyp- und Iterationsabstraktionen. 
\end{itemize}

Der Parsing-Phase folgt eine "Uberpr"ufung aller Deklarationen, um
sicherzustellen, da"s nur korrekt "ubersetzbare \TL-Module generiert werden.
Treten hierbei keine Fehler auf, so werden die vorgefundenen Typdeklarationen
als {\em Dictionary} von Typbeschreibungen in einer Datei gespeichert, um von 
anderen Spezifikationen importiert werden zu k"onnen. Die Typbeschreibungen
haben folgende Struktur:
\begin{xple}
\begin{tabbing}
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\= xxxxxx \= \kill
  \kw{Let} GDLType =\\
    \kw{Tuple}\\
        moduleName :String \>(* Name des \TL-Modules, in dem der Typ zu \\
\>definieren ist *)\\
        name, tlName :String \>(* Namen des Typs in C++ bzw. \TL\ *)\\
        isAbstract :Bool \>(* abstrakter Typ? *) \\
        passingMode :String \>(* Parameter"ubergabemodus f"ur {\sl bind} *)\\
      \kw{case} classCase \kw{with}\\
        virtuals :list.T(GDLsyntaxTree.Header) \>\>(* Liste aller virtuellen\\
\>Methodendeklarationen, incl. geerbter *)\\ 
        isForward :Bool \>(* Forward-Deklaration? *)\\
      \kw{case} baseCase, enumCase, typedefCase, defineCase \\
    \kw{end}
\end{tabbing}
\end{xple}
Sie enth"alt Information, die sowohl zur Typ"uberpr"ufung als auch zur
Generierung ben"otigt wird.

Zur "Uberpr"ufung der Deklarationen wird 
zun"achst anhand der Import-Liste der zu "ubersetzenden Spezifikation 
eine "Ubersetzungsumgebung aufgebaut, die alle in den importierten
Spezifikationen definierten Typbeschreibungen enth"alt.
Es werden folgende "Uberpr"ufungen vorgenommen:
\begin{itemize}
\item Modulglobale Bezeichner (Typnamen, Methodennamen, Namen von
Enumerator\-ele\-men\-ten) d"urfen nicht mit 
\TL-Schl"usselw"ortern oder dem jeweiligen Modul-/\-Schnitt\-stellenbezeichner 
kollidieren. Ferner d"urfen sie nicht redeklariert werden.
\item Klassendeklarationen:
  \begin{itemize}
  \item Alle genannten Basisklassen m"ussen deklariert sein.
  \item Alle in Methoden verwendeten Bezeichner m"ussen sichtbar sein.
  \item Eine "Uberdeckung von Modulbezeichnern durch Parameterbezeichner
  mu"s ausgeschlossen sein\footnote{siehe Beispiel auf Seite 
  \pageref{benennungsschema}}.
  \end{itemize}
\item {\bf typedef}: Der angegebene Typbezeichner mu"s deklariert sein.
\item Zu jeder Forward-Deklaration mu"s eine Definition existieren.
\end{itemize}

Abbildung \ref{gdl-architektur} gibt einen "Uberblick "uber die Struktur des
Generators. K"astchen symbolisieren Module mit deren Schnittstellen, wobei
Verbindungslinien Import-Beziehungen zwischen Modulen darstellen (h"oheres
Modul importiert tieferliegendes). Ellipsen 
repr"asentieren reine Datenobjekte und Pfeile entsprechend Datenfl"usse. 

\begin{figure}[hbt]
\leavevmode
\def\epsfsize#1#2{0.8\textwidth}
\centerline{\epsffile{gdl-architektur.epsf}}
\caption{\label{gdl-architektur} Architektur des Gateway-Generators}
\end{figure}



