Rexx Language Bindings für CORBA 3.0.
 
 
 
 

Björn Muschall
Eingereicht am 10.12.2000

























Inhaltsverzeichnis
 
 
 

1.Einleitung
    1.1 Aufgabenbeschreibung
    1.2 Aufbau der Arbeit

2. Die Architektur von CORBA
    2.1 Die Bestandteile des Kerns
     2.2 Die Funktionsweise des Datenaustausches

3. Die Interface Definition Language

4. Die offiziellen Language Bindings
    4.1 C
    4.2 C++

5. Die inoffiziellen Language Bindings
    5.1.COMBAT
    5.2.Rapid Corba Server Development in TCL
    5.3.weitere Language Bindings

6. Der Ablauf eines dynamischen Aufrufes

7. Language Binding für REXX
    7.1  REXX und IDL
    7.2  Das SAA-API, Statische Umsetzung
    7.3  Pseudo-objekte, Dynamische Umsetzung
 
 
 
 
 
 
 

1.1   Die Aufgabenbeschreibung
 
Die amerikanische Standardisierungsorganisation Object Management Group (OMG) entwickelt seit Jahren objektorientierte Standards. Die Common Object Request Broker Architecture (CORBA) erlaubt es verteilten Objekten über Systemgrenzen hinweg zu kommunizieren. Zentraler Bestandteil ist die Definition von Schnittstellen verteilter Objekte in einer ??Programmiersprachen übergreifenden Beschreibungssprache, der Interface Definition Language (IDL). Eine anschließende Implementierung der Architekur geschieht in einer Programmiersprache. Die OMG hat für eine Reihe von Programmiersprachen Language Bindings erarbeitet, die die Umsetzung der IDL-Definitionen und damit die Implementierung definieren (für ADA, C, C++, COBOL, JAVA und SMALLTALK) Für eine Reihe weiterer Programmiersprachen bestehen zur Zeit noch keine offiziellen Language Bindings.

Ziel der Aufgabe ist es, für die Sprache REXX den Entwurf eines Language Binding vorzubereiten, und damit die Implementierung von CORBA-Objekten in REXX zu ermöglichen. Ein erster Schritt dazu ist die Erarbeitung der Architektur und weiterer Bestandteile von CORBA, die in Hinblick auf das Language Binding zu betrachten sind. Ein weiterer Schritt ist das Auseinandersetzten mit bestehenden Language Bindings. Zuletzt wird der Entwurf eines solchen Language Bindings für REXX erarbeitet.
 
 
 
 
 
 

1.2   Der Aufbau der Arbeit:
 
Die Architektur von CORBA wird erarbeitet. CORBA selber ist eine Infrastruktur zur Realisierung verteilter Systeme. Wie diese Infrastruktur aussieht, wird im ersten Kapitel der Arbeit betrachtet.

Verteilte Systeme kommunizieren mittels Austausch von Nachrichten. Für diesen Nachrichtenaustausch ist eine Schnittstelle für das Senden und Empfangen solcher Nachrichten notwendig. Dafür notwendig sind eine geeignete Datenübertragung und Protokolle. Durch die Definition der Schnittstellen mittels IDL und der anschließenden  Übersetzung in eine Programmiersprache, die auf einem bestehenden Language Mapping basiert, wird dieser Mechanismus für den Entwickler verteilter Objekte in CORBA transparent gehalten. Dieser Mechanismus wird betrachtet. (Der Request, die Protokolle IIOP, GIOP)

Die Metadaten des Interface Repositories, die Typecodes und ihre Bedeutung für die Nachrichtenübermittlung wird genannt. Die Interoperable Objekt Referenz (IOR) ist Teil des Adressierungskonzeptes. Weiter unten werden die inoffiziellen Languagemappings für eine Reihe von Skriptsprachen untersucht. Allen Skriptsprachen fehlen mehr oder weniger die Merkmale einer stark typisierten Sprache wie sie ??IDL darstellt. Die Umsetzung von Methodenaufrufen erfordert Typinformationen. Dieser Abschnitt bereitet die Betrachtung der inoffiziellen Language Bindings für eine Reihe von Skriptsprachen vor.

Die Interface Definition Language(IDL) wird betrachtet.

Die offiziellen Language Bindings bestehen für eine Reihe von Programmiersprachen. Vorgestellt  werden die Language Bindings für C,- und C++.

Eine Reihe von inoffiziellen Language Bindings wird betrachtet. Die hier betrachteten Sprachen sind wie REXX ebenfalls Skripsprachen. Im Gegensatz zu den obigen Programmiersprachen, weisen sie einige Besonderheiten auf. Die Ansätze sind teilweise in dynamische und statische zu unterteilen.

Da einige der vorgestellten Lösungen auf dem dynamischen Generieren von Request basiert, und dieses ein immer gleich ablaufendes Schema darstellt, soll hier ein typischer dynamischer Methodenaufruf gezeigt werden.

Die Möglichkeiten ein Language Binding für REXX zu gestalten werden vorgestellt
 
 
 
 
 
 

2. Die Architektur von CORBA
 
CORBA ist eine Infrastruktur zur Realisierung verteilter Systeme. Die Bestandteile eines solchen Systems können über Prozessgrenzen, sogar über Rechnergrenzen hinweg verteilt werden. Aus Sicht eines Entwicklers, der sich einer Programmiersprache bedient, um diese Bestandteile zu implementieren, läßt sich das System nicht mit den alleinigen Mitteln seiner Programmiersprache, wie Funktionen, Modulen, und  Aufrufbeziehungen  realisieren. Mittel und Wege über Programmiersprachengrenzen hinweg werden benötigt. Solche Möglichkeiten sind vielfach schon genutzt worden:


Ein Aspekt von CORBA ist, daß die Bestandteile seiner Architektur in einheitlicher Sicht in Form von Objekten dargestellt werden. Eine grundlegende Eigenschaft dieser Objekte ist, daß sie über ihre Schnittstellen beschrieben werden, welche eine Abstraktion von der Implementierung der Objekte darstellen. Die Implementierung dieser Objekte kann dann in der Programmiersprache der Wahl erfolgen. Die Schnittstellenbeschreibung wird  in einer einheitlichen Form, mittels einer descriptiven Beschreibungssprache spezifiziert, der Interface Definition Language (IDL). Diese läßt sich dann über die Language Bindings auf die jeweiligen  Programmiersprachen abbilden.

§§Ein weiterer Aspekt ist, daß diese Abbildung nicht auf direktem Wege geschieht. Zwar müssen die Konzepte die die IDL beinhaltet(Modellierungskonzepte wie Objekte und Vererbungsbeziehungen, das Typenkonzept einer streng typisierten Sprache, Namensraumstrukturierung) ein entsprechendes Pondon in einer anderen Programmiersprache haben, oder sich zumindest mit anderen Mitteln abbilden lassen,§§§ intern wird ein Aufruf einer entfernten Methode aber mittels dem Versenden von Nachrichten realisiert, von denen jedoch abstrahiert wird, um dem Entwickler innerhalb seiner Programmiersprache eine transparente Sicht zu geben. Die Transparenz besteht darin, Methoden entfernter Objekte so aufzurufen, als wären sie Methoden lokaler Objekte.
 
 
 


    2.1 Die Bestandteile des Kerns (Corba Core)
 

Zum Kern von CORBA wird das Objektmodell, der Objekt Request Broker (ORB), die Schnittstellen zum ORB, und die IDL gezählt. Die Schnittstellen unterteilen sich weiter  in das ORB-Interface, die statischen und dynmischen Interfaces, und den Objekt Adaptern
 

Objektmodell:
Im Objektmodell werden neben den Eigenschaften von Objekten, dies sind Operationen und Attribute, auch Schnittstellen, und Typen vereinbart. Dabei unterscheidet CORBA grundsätzlich zwei verschiedene Typengruppen, die einfachen und die konstruirten Typen. Konstruierte Typen sind solche, die sich wiederum aus einfachen zusammensetzten. Zu den Datentypen gehören auch die Objektreferenzen und darüberhinaus Exceptions und Datentypen wie der ANY oder neuerlich der VALUETYPE, die beliebige andere Typen aufnehmen können. Die Objektreferenzen unterteilen sich in domäneninterne und die übergreifenden, externen, interoperablen Objektreferenzen (IOR), die der eindeutigen Identifikation den ORB übergreifend, und damit weltweit, dienen soll.
 

IDL
Interface Definition Language (kurz IDL), beinhaltet:
    Die syntaktische Beschreibung der IDL
    Die in IDL geschriebene Spezifikation der elementaren Schnittstellen
    Die Language Mappings
 

Der Object Request Broker (ORB) und die ORB-Domäne
Die Gesamtheit aller Objektimplementierungen und deren Instanzen nennt man ORB-Domäne. Der ORB stellt den Backbone dieser Objekte und eine Sammlung von Vorschriften der Interaktion zwischen den Objekten dar. Es ist weder vorgeschrieben, noch wahrscheinlich, daß der ORB nur aus einer Komponente besteht, oder daß es sich um ein konkretes Objekt handelt, vielmehr ist er eine logische Struktur, die über viele Objekte einer Domäne verteilt ist. Er ist ein abstraktes Konstrukt. Jedoch gibt es in dem meisten Implementationen ORB-Produkten ein Orbobjekt, in Form eines Pseudoobjektes.
 

Interfaces
Direkt an den Orb angeordnet, und damit auch zum Kern von CORBA gehörend, findet man die Interfaces. Diese lassen sich in statische und dynamische sowie die ORB-Interfaces unterteilen. Zugriffe auf entferne Objekte sollen aus Sicht des aufrufenden Objektes transparent sein, dafür benötigt man lokale Stellvertreter, deren Methoden die gleichen Signaturen wie die entfernten Methoden haben, sogenannte Proxy-Objekte. Zu jeder Implementierung eines entfernten Objektes muß es ein §§vorgeschaltetes, also eine korrespondierende Implementierung eines ProxyObjektes geben.

In CORBA gibt es den Stub und den Skeleton, welche die statische Variante der Proxyobjekte darstellen. Die dynamische Variante ist mit dem Dynamic Invocation Interface (DII) und für die Server-Seite mit dem Dynamic Skeleton Interface (DSI) vertreten. Das DII stellt die vollständige Funktionalität zur Verfügung, um entfernte Aufrufe dynamisch erzeugen und ausführen zu können. Durch das DSI können Anwendungen eingehende Anfragen dynamisch bearbeiten.
 

Interface Repository (IR)
Das IR ist ebenfalls an den ORB angegliedert und dient der Erfassung von Schnittstelleninformationen, auf die zur Laufzeit entfernt zugegriffen werden kann. Daher liegen diese in maschinenlesbarer, von der IDL-Definition direkt abgeleiteter und damit in genormter Form vor. Das Interface Repository ist wiederum aus CORBA-Objekten aufgebaut. Es enthält alle mittels IDL spezifizierten Informationen, bietet auf Definitionen mittels Pseudo-Interfaces Zugriff. In diesem Interface Repository werden Operationssignaturen und Vererbungshierarchien der Objekte transparent aufbereitet, aufgelöst.
 

Objekt Adapter
Der Object Adapter bietet eine Schnittstelle zum Kern des ORB, und damit zu zentralen Dienstleistungen wie das Erzeugen und Interpretieren von Objektreferenzen, das Aktivieren und Deaktivieren von entfernten Objekten. Entfernte Objekte sind meist in Form von Servants realisiert. Ein Server kann mehrere Servants beinhalten. Ein Objekt Adapter dient der Registrierung von Servants und des Weiterleitens von Aufrufen an diese. Ein Servant ist der reale Stellvertreter eines Objektes. Das Objekt selber ist abstrakt, ein Servant ist die Implementierung eines Objektes in einer Programmiersprache. Ein Sevant muß bekannt sein, eine Identität haben. Diese verschafft ihm der Objekt Adapter.
 

Common Object Services (COS)
Die COS sind nicht mehr Bestandteile des Kerns, sondern bieten, auf diesen aufbauend, zustätzliche Funktionalität. Sie sind gesammelte und definierte Standarddienste, die für die Entwicklung von verteilten Anwendungen eine Vereinheitlichung bedeuten, und das Entwickeln erleichtern, da sie nicht ständig neu erfunden und implementiert werden müssen. Jeder Dienst hat eine genormte Schnittstelle, diese kann auch aus mehreren IDL-Interfaces bestehen.
Einer dieser Dienste ist gerade in Hinblick auf den dynamischen Aufruf von Interesse:
Einer der zentralen Dienste, gerade auch im Hinblick auf die dynamischen Methodenaufrufe ist der Naming Service. Er dient als zentrales Verzeichnis für Objektreferenzen und verwaltet diese. Er ermöglicht das Auflösen von Referenzen auf Objekte für andere Objekte.
 

Naming Service
Aufgabe des Naming Service ist es, beliebig viele CORBA-Objekte unter frei wählbaren Namen zu erfassen. Ähnlich wie in einem Dateisystem ordnet er die Referenzen der Objekte  hierarisch in Kontexten an. Kontexte sind dabei vergleichbar mit Verzeichnissen und die darin angeordneten Adressen mit Dateien. Da er das Ermitteln aller anderen benötigten Objektreferenzen erst ermöglicht, stellt er die erste, initale Objektreferenz dar, die ein Objekt kennen sollte.
Ein solcher Naming Service kann auch Kontexte unterschiedlicher Domänen enthalten.
 

Abbildung1: Die Architektur des ORB

 
 
 

    2.2 Die Funktionsweise des Datenaustausches:
 
 

In Abbildung 1 wird die Architektur und Funktionsweise von CORBA gezeigt. Auf ihr ist zu sehen, daß der Aufruf von Methoden in das Versenden von Requests resultiert.

Ein Designaspekt von CORBA ist, dem Programmierer den Aufruf einer entfernten Operation genauso erscheinen zu lassen, als würde er die Methode eines lokalen Objektes aufrufen. Realisiert wird dies, indem transparent Nachrichten erzeugt werden. Diese nennen sich hier Request. Ein solcher Request wird erzeugt, und kann über System,- und Prozeßgrenzen hinaus verschickt werden. Für diesen Nachrichtenaustausch ist eine Schnittstelle für das Senden und Empfangen solcher Nachrichten notwendig. Ebenfalls notwendig ist eine geeignete Form der Datenübertragung und Protokolle.

Im Falle CORBA lassen sich Requests mittels dem Protokoll IIOP bilden. Aus den Spezifikationen der OMG geht hervor, daß die Kommunikation  innerhalb einer Domäne relativ frei implementierbar ist, die zwischen den Domänen aber streng definiert. Interaktionen über Domänengrenzen hinaus werden durch das IIOP Protokoll beschrieben. Innerhalb eines ORB  kann jedoch ein beliebiges Protokoll implementiert sein, solange gewährleistet ist, daß dieses nach außen über eine sogenannten Bridge in das IIOP  Protokoll übersetzt werden kann.

Dies bedeutet, daß der Entwickler irgendwann an den Punkt gelangt, an dem er seine Methodenaufrufe in die Form von  IIOP Requests wandeln muß, oder eine Möglichkeit findet, diese Arbeit, die für andere Sprachen bereits geschehen sind, einzubinden. Er muß damit verbunden eine Reihe von Marshalling-Routinen selbst bereitstellen, oder durch Integration von Stubs, die diese Logik bereits fest integriert haben, und beispielsweise in einer Sprache wie C++ realisiert wurden, wiederverwenden. Ein später vorgestellter Ansatz nutzt  die Möglichkeiten einer Skriptsprache, in C oder C++ realisierte Stubs einzubinden.

Unter dem Marshalling versteht man die Umsetzung eines Methodenaufrufes in eine Nachricht. Eine solche Nachricht benötigt eine Übertragungsform, die unabhängig von unterschiedlichen Rechnerarchitekturen ist. Eingesetzt wird daher eine Umwandlung der Daten in eine netztaugliche Form, im Falle CORBA ist dies  die Common Data Representation (CDR). Die Strukturierung der Nachricht, ihre Syntax, wird durch das Protokoll vorgegeben.
 
 
 

Type Codes

Die Metadatensprache von CORBA ist IDL, das Metadaten-Repository von CORBA ist das IR. CORBA nutzt Type Codes, um jeden IDL-Datentypen mit einem global eindeutigen Identifizierer zu verbinden. Somit werden Daten anhand ihrer eindeutigen Identifizierer selbstbeschreibend. Die Typecodes sind über bestimmte Methoden zu erhalten, und können auch dynamische aus dem IR erhalten werden
Wie bereits erwähnt wurde, ist  IDL eine streng-typisierte Sprache. Anhand genannter Type Codes kann auch die Typüberprüfung auf Seiten des ORB erst ermöglicht werden. Zudem wird über diese Codes bewirkt, daß unterschiedliche ORBs eindeutige Typen verwenden.
Wie weiter unten gezeigt wird, ist ein Nebeneffekt dieser Type Codes, daß man ihre Information für die dynamische Generierung von Requests benötigt. Da ein Request einem Methodenaufruf entspricht, sind wie bei dem Aufruf von Methoden ebenfalls die Typinformationen der Argumente und des Rückgabewertes von Interesse.
 
 

Das Internet Interorb Protokol (IIOP)

Die Protokolle GIOP und IIOP laufen unter der Fassade der CORBA-Architektur. Die in IDL spezifizierbaren Interfaces bilden aus Programmiersicht die APRs zu diesen Protokollen. Für den direkten Zugang zu diesen Mechanismen exisitieren keine Schnittstellen, diese Protokolle werden automatisch vom ORB verwendet und sind damit transparent für den Entwickler.
Das General Inter Orb Protokol (GIOP) liegt eine Ebene über dem IIOP. Das  IIOP ist die konkrete Ausprägung des GIOP für TCP/IP-basierte Netze. Da dieser Netztyp am weitesten verbreitet ist, ist IIOP der Kommunikationsstandard. Im Rahmen der Interoperabilität -das ist die Fähigkeit eines Clients von ORB A eine in IDL definierte Operation eines Objektes, das sich an einem ORB B befindet, aufzurufen- verbindet das IIOP ORBs unterschiedlicher Hersteller untereinander. Nach außen hin muß ein ORB zumindest eine Umsetzung des internen Protokolls auf das IIOP leisten.
Da es sich anbietet, als ORB-internes Protokoll gleich IIOP zu wählen, um sich diese Umsetztung zu ersparen, haben einige ORBs als internes Protokoll das IIOP gewählt, ein Beispiel ist der ORB MICO.
Die weiter unten beschrieben Anbindung der Sprache TCL an CORBA im Falle des ORB TCL-IIOP", erfolgt eine Erzeugung dynamischer Requests mit einer direkten Umsetztung des Requests in eine IIOP-Nachricht.

Im Gegensatz zu anderen Kodierungsverfahren sind im IIOP keine Angaben zur Datentypisierung integriert. Besonders wichtig wäre dies für die Argumente und Rückgabewerte der aufgerufenen Methoden. Diese Angaben kann man über die Schnittstellen der Objekte erfragen, oder direkt über das IR, wie im Abschnitt zu den Type Codes schon erwähnt.
Für das Marshalling - das ist die Umsetzung eines Methodenaufrufs in eine Nachricht- ist diese Typinformaton  unerläßlich. Das Marshalling hat nicht nur die Aufgabe, dem Protokoll zu entsprechen, sondern auch eine Bestimmte Repräsentation der Bestandteile zu gewährleisten. Diese Repräsentation wird durch die Common Data Representation (CDR) beschrieben.

###Ein weiteres Charakteristikum ist, daß es dem ORB frei gestellt ist, in welcher Reihenfolge der Bitrepräsentation, auch Byte Order genannt, er seine Daten codiert, er muß die angewandte Byte Order lediglich an einer bestimmten Stelle auszeichnen. Die Bestandteile, dies sind die einzelnen Daten, werden wie die Elemente in C-Strukturen an gewissen Positionen ausgerichtet, und die entstehenden Lücken aufgefüllt.
 
 

Die Interoperable Objekt Referenz (IOR)

Sinn einer IOR ist es ein Objekt weltweit zu identifizieren.
Um weltweit eindeutig zu sein benötigt die IOR ihre Bestandteile, einen vom ORB vergebenen Schlüssel sowie für die Unterscheidung des ORB seine IP-Adresse und den dazugehörigen Port. Die IOR wird in zwei Teilen spezifiziert, einen netzwerkspezifischen Teil, der durch die IIOP-Spezifikation bestimmt wird -solange es sich um ein TCP-IP-Netz handelt- und einen sehr generell gefaßten, durch die GIOP-Spezifikation gegebenen.
In der IOR ist das IOP, das Interoperability Profile enthalten, das die oben erwähnte Adresse des ORB enthält, darüberhinaus aber noch eine weitere ORB-spezifische Objektreferenz, die zumeist eine Speicheradresse darstellt, die nur der erzeugende ORB versteht. Der Aufbau der Informationen der IOR bestimmt sich nach der CDR, und einer Tatsache, das Alignment, die Anordnung von Datentypen an bestimmten "geraden" Positionen in einem Byte Stream.
 
 
 

3. Die Interface Definition Language (IDL)
 
 
Die Interface Definition Language ist eine Sprache zur einheitlichen, implementierungsunabhängigen Beschreibung der exportierten Attribute und Methoden von entfernten Objekten. Ihr zentraler Bestandteil sind Interfaces, die zu Modulen gruppiert werden können und damit ein Konzept der Namensraumstrukturierung darstellen.
Das sogenannte Interface spiegelt die Schnittstelle eines Objektes wieder. Grundsätzliche Konstrukte sind Operationen, Schnittstellen und Module. Darüberhinaus ist IDL deskriptiv, ihr fehlen operationale Elemente, algorithmische Aspekte, und im Gegensatz zu einigen Skriptsprachen ist sie typisiert.
Die OMG standardisiert die Sprachbindungen, um diese Konstrukte in andere Sprachen zu übersetzen und löst damit auch eine Reihe von Abbildungsproblemen, da jeder Sprache andere Strukturierungskonzepte unterliegen. Einige Sprachen sind objektorientiert. Unter den objektorientierten Sprachen gibt es unterschiedliche Klassenkonzepte.(zB  Ein Java Interface entspricht in C++ einer abstrakten Klasse. )
IDL-Spezifikationen ähneln syntaktisch den Klassendeklarationen in C++. Die Entsprechung zu einer C++ Klasse ist dabei eine Schnittstelle, oder IDL-Interface. Innerhalb dieser Schnittstelle  werden die vollständigen Signaturen angegeben.
Einen Vererbungsmechanismus bietet IDL ebenfalls. Interfaces können von anderen Interfaces erben, dies auch in mehrfacher Weise. Das Überladen oder Überschreiben von geerbten Methoden ist aber nicht möglich. Dies auch aus dem Grunde, eine Kompatibilität zu Sprachen, die keine Objektorientiertung unterstützen, zu gewährleisten.

Interfaces sind Klassendefinitionen ohne Implementationssektion, also ohne angehängte Methodendefinitionen. Operationen sind Methoden, mit Rückgabewert, Parametern und der Fähigkeit Ausnahmen aufzuwerfen und eine Kontextbeschreibung mitzuliefern.
Datentypen, wobei der Typ ANY, der jeden anderen Typ aufnehmen kann, besonders interessant ist. Er ermöglicht polimorphe Aufrufsituationen, mit Parametern, die zur Kompilierzeit noch nicht feststehen.
 

IDL beinhaltet eine Reihe von einfachen Datentypen:

Desweiteren eine Reihe von konstruirten Typen: Eine Sonderstellung nehmen Typen ein, wie die Exception und die ObjektReferenzen, von denen es zwei unterschiedliche gibt.
 

Ein weiteres Merkmal, das IDL auszeichnet, ist, daß es den Mechanismus des Exception Handling unterstützt, und dieser in allen Language Bindings auf die Zielsprachen überträgt.
 


 

4. Die offiziellen Language Bindings
 
 

    4.1 C Language Binding
 

Aufgrund mangelnder objektorientierter Eigenschaften der Sprache C ist eine Konvention getroffen worden, über die entfernte Objekte unterschieden werden können:
Funktionen des Stub wird bei Aufruf als zusätzliches Argument die Zielreferenz des Zielobjektes, sowie eine Environment Variable übergeben.
Klassendefinitionen werden dadurch unterschieden, daß die zu je einer Klasse gehörenden Operation über einen zusammengesetzten Namen identifiziert werden, in der Form, daß der Name des Interface (der Klasse) und der Name der Operation in der Form Interface1_operation1() zusammengebunden werden. Der Bezeichner der Klasse ist implizit im Bezeichner der Methode enthalten.

siehe an einem Beispiel:
    interface Bsp1{
            int op1(in int etwas)}

wird zu
    extern Corba_int   Bsp_op1(Bsp1 zielref, Corba_int etwas, Corba_Environment *ev);
 

Die Zielreferenz wird dabei benötigt, da die Form einer Dereferenzierung der Form Bsp.op1() wie in C++ üblich, nicht zur Verfügung steht.
 

Über das Language Mapping wird die Verantwortung für die Speicherallozierung und Dealloziereung in Rollen dem Client oder Server zugewiesen. Je nach Parametertyp (in ,inout, out) wird Speicher für die Argumente auf unterschiedlicher Seite alloziiert oder dealloziiert, was dann in getrennten Adressräumen geschieht. Daher bietet CORBA Möglichkeiten dafür, sozusagen CORBA-spezifische Objektreferenzen, die nicht automatisch durch die programmierspracheneigene Laufzeitumgebung gelöscht werden können.

Da die IDL-Typen einen Wertebereich verbindlich festlegen, muss es entsprechende C++ Typen mit dem gleichen Wertebereich geben. Einfache Typen in C++ weisen aber von Plattform zu Plattform unterschiedliche Speicherlayoute auf. Anders als bei Java, wo die interne Darstellung der Datentypen plattformübergreifend genormt ist, sind bei der Implementierung von C und C++ Compilern die Darstellungen der Datentypen an die Möglichkeiten der unterschiedlichen Plattformen angepaßt worden. Die eine oder andere Architektur hat eine andere Wortlänge, ein anderes ByteOrdering...etc. Ein int ist 32bit groß auf einem PC aber auf einer Workstation eben nicht. Daher wurde ein indirektes Mapping auf Typen mit dem Suffix "Corba_" gewählt:
 

    idl:    long   C: Corba_long
    idl:    int   C:    Corba_int
    ...

Vererbung von Interfaces können  in einer objektorientierten Sprache besser abgebildet werden. Zur Erinnerung, ein Interface in IDL wird auf eine Klasse in C++ abgebildet. So sind die Funktionen, die eine abgeleitete Klasse erbt, implizit in ihr enthalten. In C gibt es keine Klassen. Ein Interface wird auf eine Reihe von Funktionen abgebildet, die mit dem Klassennamen beginnen, zB. Interface1_op1.
Eine ererbte Funktion wird daher nochmal explizit mitaufgeführt. Erbt ein Interface2 diese Methode op1 und definiert nur eine op2 neu, so werden automatisch erzeugt:

    extern Corba_int Interface2_op1 () {}
    extern Corba_int Interface2_op () {}
//die  Methode Op1 wird also nochmal explizit aufgeführt.
 

Für das Exeptionhandling gibt es einen Struct, der die Exception abbildet, sowie ein Struct Corba_Environment, der entweder keine oder eine beliebige Exception aufnehmen kann, und den dritten Parameter einer jeden Operation darstellt.
 
 
 

    4.2 C++ Language Mapping:
 
Ein IDL-Interface entspricht einer abstrakten C++Klasse mit einigen Public-Definitionen. Diese stellt eine Basisklasse dar, die selber nicht wieder zur Bildung anderer Basisklassen genutzt werden sollte. Sie sollte daher legidlich implementiert werden. Benötigt man eine andere Basisklasse, so sollt man auf Basis der IDL-definition ein Interface von einem anderen erben lassen. Dem abgeleiteten IDL Interface entspricht dann wieder ein Basisklasse in C++.(wegen des IDL-eigenen Polymorphismus durch narrow() bezeichnet, nötig )

Ein Pointer auf ein Objekt einer Klasse muss entweder als _var oder als _ptr vereinbart werden. Dies ist notwendig für die CORBA spezifische Speicheralloziation.

Das Interface des Naming Services liefert immer eine Referenz vom Typ Objekt, um nicht auf einen einzelnen Typen beschränkt zu sein. Da aber C++ eine streng typisierte Sprache ist, muss die Refernz auf den eigentlichen Typen mittels der Methode narrow() eingeschränkt werden.

Eine Exeption wird auf ein ine C++ Klasse gemappt, die in dem jeweiligen modulxx.h File deklariert wird.. Es gibt eine Basis Exception Klasse von der die User Exceptions und die SystemExceptions abgeleitet werden und davon wieder die eigenen. Also wird die modulxx exception om CorbaModul definiert und im modulxx.h  deklariert.

Valuetype sind neu, sie vereinen Interface-Verhalten und Datentyp-Verhalten. Ein einfacher Typ wird auf einen Typ in C++ gemappt, und hat lediglich einen Zustand. Ein Interface ist lediglich ein Interface, entspricht dann einer Klasse, in der lediglich Methoden vereinbart werden, abstrakten Klassen (ohne Datentypen in Form von Attributen, da diese ja auf set und get Methoden gemappt werden). Der Valuetype soll beides vereinen.

 
5. Die inoffiziellen Language Bindings
 
Die hier vorgestellten inoffiziellen Language Binding sind für eine Reihe unterschiedlicher Skriptsprachen erstellt worden. Dabei verfolgten die Entwickler weniger die Absicht ein Language Binding mit allen Aspekten zu realisieren. Die vorgestellten Bindings haben das Ziel, die Vorteile einer gewählten Skriptsprache mit denen von CORBA zu verbinden.

Skriptsprachen wie TCL, PERL oder eben REXX bieten eine Reihe von Vorteilen gegenüber von Programmier- sprachen wie C, JAVA, C++:


Der Einsatz einer Skriptsprache in Verbindung mit Corba soll folgendes erleichtern:

Die hier vorgestellten Integrationsansätze orientieren sich an den Möglichkeiten, wie Aufrufe von Objektmethoden realisiert werden können. Wie oben bereits erwähnt, können Aufrufe einerseits auf statische, andererseits auf dynamische Weise abgesetzt werden. Der statische Ansatz sieht eine feste Einbindung der Schnittstelleninformationen verteilter Objekte in Proxyobjekten vor. Anhand der IDL wird von einem IDL-Compiler für je eine Klasse von entfernten Objekten jeweils einen zugehöriger Stub und einen Skeleton generiert. Ein Stub enthält die dem IDL Interface entsprechenden Methodensignaturen. Fest integriert in den Stub sind Marshalling-Routinen, die transparent einen Request erzeugen. Dies bewirkt, daß die Typinformation der Argumente implizit mit enthalten sind. Sollte sich die IDL-Definition einmal ändern, Beispielsweise die Anzahl und Anordnung der Argumente einer entfernten Methode, so müssen Stub und Skeleton neu kompiliert werden Dieser Ansatz ist der weniger flexiblere, aber der performantere.
Der flexiblere Ansatz, nutzt den dynamischem Aufruf. Mittels einiger Standardmethoden werden hier die Schnittstelleninformationen für einen Request zu Laufzeit erfragt, und der Request aufgebaut. Der Operationsname in Form eines Strings und der Rückgabewert sowie eine Liste von Argumenten mit ihren entsprechenden Typen wird anhand der Informationen aus dem IR zu einem Request zusammengesetzt. Dazu notwendig sind Typinformationen die vom Orb ebenso überprüft werden, nur  eben zu Kosten der Laufzeitperformanz. Änderungen an einer Schnittstelle bewirken lediglich das erneute Übertragen der Schnittstelleninformation.
Im Gegensatz zum statischen Stub und dem Skeleton ist dieses Vorgehen jedoch nicht spezifisch für eine Klasse von Objekten.
    5.1.COMBAT
Über das Language Mapping hinaus, wird eine  Infrastruktur benötigt, die das Handling von Objekt Referenzen, das Connection Management, und das Marshalling in GIOP Messages übernimmt.
Der hier gewählte Weg der Realisierung eines LanguageBinding führt über den dynamischen Methodenaufruf, wie er oben beschrieben wurde. Anhand der IDL-Definition der Schnittstelle wird nicht ein Stub erzeugt, in dem die Typinformationen der Argumente fest integriert sind, sondern der Compiler generiert die maschinenlesbare Form eines IR-Eintrages. Diese wird dann in das IR geladen, um dynamisch abgefragt werden zu können.

Der Verfasser von Mico bemängelt, daß ein GIOP Request zwar Informationen über das Zielobjekt, den Methodennamen, und die Parameter enthält, aber keinerlei Typinformationen bezüglich der Argumente übertragen werden. Diese sind aber notwendig, damit Sender und Empfänger wissen, wie die eingehenden binären Daten zu interpretieren sind. .
Selbst die IOR, die die Adressierungsinformationen für verschiedene Netzwerke enthalten, enthalten keine Typinformationen, darüberhinaus sind sie teilweise undurchsichtig. Die einzige Introspektive die Corba bietet, ist daß mittels der definierten Methode corba::type() Type Codes aus dem IR zu beziehen sind, und damit die Typprüfung möglich ist.
 

Bis Tcl 8.0 war die einheitliche Datenrepräsentation der String, mit TCL8.0 wurde ein ein Typsystem rückwärtskompatibel hinzugefügt,  in dem zwei Repräsentationen nebenherlaufen, die interne und eine stringifizierte. Um einen eigenen Typ hinzuzufügen, müssen Hin,- und Rückkonvertierungsfunktionen bereitgestellt werden. Strings bleiben der unterste Nenner, bleiben gemeinsame Repräsentation. "whenever a  value is requested to have a certain type  the old type updates the string represantation and the integer type for example scans the string."
Die IDL-Typen werden nach dem COMBAT-Mapping übersetzt. Zwei denkbare Möglichkeiten bieten sich an: eine langsame, die COMBAT nutzt, also die Übersetztung auf TCL-Typen, und damit die Verwendung der Typen Int, Boolean, Double, String und als komplexen Typ eine Liste, oder eine Alternative, das Mapping undurchsichtig zu gestalten, mit Zugriffsfunktionen für je einen unterschiedlichen Typen zu gestalten.

In Combat wird zu je einer Objektreferenz eine TCL-Prozedur -Handle genannt- erstellt, die Typinformationen und die Objektreferenz enthält. Dieses Handel interpretiert das erste Argument als Operationsnamen, und die übrigen als Parameter für diese Operation.
Ein solcher Handle "marshalled" die Parameter in eine GIOP-Nachricht und läßt sie über den ORB transportieren. Für jedes Handle muß ein existierender Eintrag im IR gefunden werden, damit das Marshalling überhaupt erst umgesetzt werden kann. Auf einen Aufruf der Methode get-interface() auf einem entfernten Objekt wird ein Zeiger auf einen Eintrag in einem entfernten IR returniert, einem IR Record.
Das Vorgehen in COMBAT im Detail sieht folgendermaßen aus:
Die Client-Seite wird generiert, indem IDL-Definitionen in eine Datei geschrieben werden. Ein Compiler generiert aus jener Datei xxx.idl dann eine solche der Form xxx.tcl, die innerhalb eines Skriptes für den Client genutzt werden kann. Wird dieses Skript dann "gesourced" , steht danach in einer Variablen -ir-xxx die Information, welche in das IR eingetragen wird. Das Eintragen geschieht im Skript auf Client-Seite, bevor irgendwelche Kommandos zur Ausführung gelangen.

Ein Handle muß erzeugt werden und wird benötigt, um Operationen in der Form auszuführen:
$handle operationX <parameter>        //operation wird ausgeführt
$handle attributX                                 //operation ist  "$handle read attributX"
$handle atrributX zusetzenderwert      //operation ist   "$handle set attributX wert"

Ein solches Handle, ist ein TCL-Kommando das zu einem Serverobjekt korrespondiert. Operationen auf dem Handle bewirken Ausführung auf dem Server. Also ist das Handle ein Proxyobjekt. Mittels corba::string-to-objekt() erhält man ein Handle, das man in einer Variablen ablegt.
Da COMBAT seine Informationen bezüglich der Operationen wiederum aus einem IR zieht, muß für jedes Handle zumindest ein Eintrag im Interface Repository vorliegen (ein IR-Eintrag korrespondiert zu einem Interface, ein Handle ebenfalls)

Realisiert wurde diese Implementierung in C++, und läßt sich auf jedem ORB installieren, das ein entsprechendes Language Mapping für C++ bietet. Es bildet somit ein "Glue Package", eine eben nicht rein in TCL implementierte Lösung
 
 
 

   5.2. Rapid CorbaServer Development in Tcl
 
Diese Implementierung stammt aus einem zur Usenix Konferenz unterbreitetem Vorschlag Rapid CorbaServer Development in Tcl [] und beschreibt eher, wie innerhalb von Tcl ein entferntes Objekt angesprochen werden kann, als eine wirklich saubere Form eines Language Bindings.
"Zukünftige Applikationen werden Dinge wie starke Typisierung und Vererbung nicht als primäre Forderung stellen, sondern die Möglichkeit, Informationen und deren Anwendungen, die in verschiedensten Sprachen realisiert sind, miteinander zu integrieren".
Die Idee des Artikels ist, das Core As Scripting Language, also den Kern einer Anwendung, die eine Menge bestehender Anwendungen kombiniert und anderen integriert, in einer Skriptsprache zu implementieren. Einige der Komponenten einer solchen Anwendung befinden sich lokal, und sind nicht in TCL realisiert, aber profitieren von den Möglichkeiten TCLs der Einbindung, andere sind entfernt und profitieren von den Möglichkeiten der Verteilung durch CORBA.

Das Bindeglied zwischen  TCL und einem ORB wird unter Nutzung von in C++ kompilierten Stubs und Skeletons gebildet. Bedenkt man jedoch, daß dieser Ansatzt hier im Gegensatzt zu den bereits vorgestellten ein "statischer" ist, sind mit häufig anfallenden Änderungen der IDL-Definitionen von Interfaces auch erneute Kompiliervorgänge verbunden.

Das Design bestimmte weiterhin, daß nicht nur der Client in TCL geschrieben sein könnte sondern der Server, der ja die entfernten Prozeduren enthält, und damit den Hauptanteil der Applikationslogik, ebenfalls. Dafür muß ein solcher Server einen TCL-Interpreter enthalten, in dem die IDL-Methodenaufrufe an gleichlautende TCL-Kommandos weitergeleitet werden.
Im Client, in dem der Aufruf der Methode stattfindet, sollen diese Kommandos wie übliche Kommandos ausehen, die in einer Shelle aufgerufen und im TCL Interpreter ausgeführt werden. Daher mußte eine Shell für den Clienten so erweitert werden, daß gewährleistet ist, daß die bisherigen Funktionen der Shell unangetastet im lokalen TCL Kernel umgesetzt werden, die neu hinzukommenden, entfernten aber transparent umgeleitet werden. (In diesem Zusammenhang kann man konzeptionell die Shell und den Kern trennen. In der Client-Shell werden die Kommandos aufgerufen, in dem Kern der Serverseite sind die Kommandos verankert.)

Die zentrale Frage zu Beginn ist, wie man CORBA-Objekte auf typenlose TCL Strings mappen kann.
Eine vorgeschlagene Möglichkeit ist, jeden Datentyp in TCL als paarweiser Zuordnung von Wert und Datentypbezeichner zu betrachten, somit die Typinformationen gleichsam mitzuführen, und anhand dessen das Marshalling umzusetzen
Eine andere Möglichkeit ergibt sich, wenn man die mittels eines vom ORB unterstützen C++ Mapping generierten statischen Stubs und Skeletons als Bindeglied benutzt und das damit bereits dort gelöste Marshalling der Methodenaufrufe umgeht.
Dann hat man allerdings das Problem, wie nunmehr die TCL Strings in die jeweiligen C++ Typen umgewandelt werden, die innerhalb der C++ Proxy für Marshalling benutzt werden.

Bedenkt man, daß die Typinformation bei einem Methodenaufruf durch die Anordnung der formalen Argumente implizit enthalten ist, braucht man sie nicht explizit mitzuführen. Da die IDL-Definition der Methoden maßgeblich für die Erzeugung der entsprechenden C++ Methodensignaturen in den Proxys ist, weiß man immer, daß das erste Argument einer Methode von einem bestimmten Typ ist. Erstellt man desweiteren einmalig eine Reihe von Konvertierungsfunktionen für die Umwandlung der TCL Strings in C++ Typen, so ist die zu lösende Aufgabe, diese Konvertierungsfunktionen in Abhängigkeit von den in einer IDL-Datei definierten Typen, mit den generierten Proxyobjekten zu verknüpfen. Jeweils ein Paar für die Kovertierung von TCL nach C++, sowie von C++ nach TCL, Convert::form_tcl und Convert::to-tcl() wird erstellt.
Laut der Beschreibung ist dies eine mittels Skripten leicht zu automatisierende Aufgabe.


Abbildung2 : Umsetzung des vorgestellten Bindings
    5.3.weitere Language Bindings
 
CORBA Script:
Ist eine eigens für CORBA-Zwecke neu geschriebene Skriptsprache. Sie bietet objektorientierte Eigenschaften in Form von Klassen und erlaubt Mehrfachvererbung und Polymorphismus. Mittels Modulen  wird es auch möglich, wiederverwendbare Programmteile in eine Package zusammenzufassen und in einem eigenen Namenraum zu kapseln. Das bestehende Language Mapping basiert auch hier auf dem Dynamischen Aufruf und dem Erhalt der nötigen Typinformationen aus dem IR zu Laufzeit. CORBA Script selber ist mittels C++ realisiert worden. Die Implementierung bietet sogar eine Schichtenarchitektur, in der die unterste Schicht vom darunterliegenden ORB abstrahiert, mit der Begründung, daß -trotz Standardisierung- Funktionssignaturen und deren Elemente von ORB-Produkt zu ORB-Produkt voneinander abweichen.
 
 

TCL-DII und seine Neuauflage TCL-IIOP. Beiden ist ebenfalls eine Umsetzung mit Hilfe des Dynamischen Methodenaufrufs gemeinsam. Die Typinformation zur Umwandlung der Argumente resultiert jedoch nicht aus einer Abfrage des Interface Repositories, sondern aus mitgeführen Tags oder Type Codes, die der Programmierer mit den Argumenten mitführen muß. Der dynamische Aufruf geht über eine einzige Methode orb_call(). Dieser werden als Argumente der Bezeichner der aufzurufenden Funktion, gefolgt von einem Platzhalter für den aufzunehmenden Rückgabewert und die einzelnen Argumente paarweise mit Bezeichner und Typangabe übergeben.
Dies sieht in etwa so aus:     orb_call  $result  methodname    f  1.35
Weiterhin zu erwähnen bleibt, daß beide Lösungen nur die Clientseite abdecken.
 

Fnorb mittels Phyton. Dieser Ansatz unterscheidet sich in sofern, daß Requests direkt in Form von IIOP-Nachrichten verpackt und versendet werden.
Bsp:  orb = corba:orb_init(argv, Corba:orb_id)
        object = orb.string_to_objekt(StringIor)
        object.methodname($etwas)
 
 

COPE
An dieser Stelle sollte kurz COPE vorgestellt werden. COPE bietet auch eine Integration von PERL und CORBA. Wer COPE gerne ausprobieren möchte, muß schnell feststellen, daß dies eine Implementation ist, die wie die oben vorgestellte Lösung TCL-DII  von einer speziellen ORB-Implementation abhängig ist, da die Umsetztung der IDL Information in TCL-DII mit Hilfe von proprietären Type Codes aus dem IR stattfindet. Der IDL2PERL-Compiler setzt hier das Interface Repository des ORBACUS voraus. Das Verfahren ist, daß nur einmalig Skeleton und Stub generiert werden unter Zuhilfename des Information des IR.
 
 
 
 
 
 
 

6. Der Ablauf eines dynamischen Aufruf
 

Abbildung3 : Der Ablauf eines dynamischen Methodenaufrufs
In Abbildung 2 ist der Ablauf eines dynamischen Methodenaufrufs dargestellt. Im vorherigem Kapitel wurde erwähnt, daß einige der inoffiziellen Language Binding Methodenaufrufe dynamisch erzeugen. Zwar benutzen diese Language Binding nicht unbedingt die hier vorgestellten Methoden, und mögen das Erzeugen von Request auch in der eigenen Sprache realisieren,  eine gemeinsame Problematik wird hier aber deutlich: die der Pseudoobjekte, die innerhalb der jeweiligen Programmiersprache verfügbar sein müssen.
 

1. Erlangen von Zugang zum ORB
Vorraussetzung um an der Corba Kommunikation teilzunehmen ist, daß ein Client einen Zugang zum seinem ORB erhält. Dazu muß es ein sogenanntes ORB-Objekt erzeugt und initialisiert werden.
Dieses ORB-Objekt ist ein spezielles Objekt, es ist ein Pseudoobjekt. Pseudoobjekte sind Objekte, die im lokalen Adressraum der verwendeten Programmiersprache liegen, und genauso, wie entfernte CORBA-Objekte behandelt werden, was bedeutet, daß aus Sicht des Programmierers kein Unterschied in den Methodenaufrufen zu erkennen ist.
Ist dann der ORB bekannt, muß ein weiteres Pseudoobjekt, der Objektadapter erzeugt werden. Mittels boa_init() wird dieses dann initialisiert.

2. Erlangen einer Objektreferenz eines entfernten Objektes. Dies kann über einen Nameservice oder Traderservice laufen. Über ihre Objektreferenz können entfernte Objekte aufgerufen werden. Diese Objektreferenz ist vergleichbar mit einer Referenz in einer Programmiersprache, nur daß sie eben nicht auf den lokalen Adressraum einer Laufzeitumgebung beschränkt ist.

3. Erlangen einer bestimmten MethodenBeschreibung. Über eine Objektreferenz kann die Methode get-interface() aufgerufen werden, um eine Referenz auf ein InterfaceDefObjekt zu erhalten. Dieses ist ein Bestandteil eines Interface Repositories und ermöglicht Auskunft über ein Interface eines Objektes, sowie deren Bestandteile zu geben.

4. Eine Argumentliste wird die Parameter, die der entfernten Methode übergeben werden, enthalten. Eine Argumentliste ist eine selbstdefinierende Datenstruktur. Sie wird für den Aufruf erzeugt und ist ebenfalls ein Pseudoobjekt.

5. Der Aufruf wird ausgeführt.
 
 
 

7. Language Binding für REXX
 

    7.1  REXX und IDL
 

REXX selber weist eine Menge Gemeinsamkeiten zu den hier vorgestellten Skriptsprachen
Hier wird nun versucht, darzustellen, auf welche Rexxeigenschaften sich IDL konzeptionell abbilden läßt.:
Die einfachen Datentypen lassen sich wie bei den anderen Skriptsprachen auf Strings abbilden
Für komplexen Datentypen ist dies ebenfalls möglich, sofern man wie in COMBAT die entsprechenden Wandlungsroutinen implementiert hat.

Für die Operationen, die zu einem IDL-Interface gehören, muß im klassischenRexx dann ein ähnlicher Ansatz genommen werden, wie bei C. Werden mangels Objektorientierter Eigenschaften im Klassischen REXX, die in IDL dort genannten Operationen auf Funktionen, oder in REXX genannt Subroutinen abgebildet, so muß eine Referenz eines konzeptionellen Objektes immer als erstes Argument mitgeführt werden. Daß die Methode eines bestimmten Objektes eindeutig bestimmt ist, ergibt sich in der Objektorientierung mittels der Quilifizierung durch Dereferenzierung des Objektes der Form Objekt1.methode1(). Mittels Funktionen kann diese Qualifizierung jedoch nur über eine Konvention in der Namensgebung erreicht werden: Objekt1_methode1(). Eine wirkliche Form der Kapselung ist dies nicht, reicht aber, wenn man diese Namenskonvention nicht verletzt.

Für den Namensraum, der durch IDL Module gegeben ist, sowie die Interfaces, fehlt hier der Ansatz. Orientierung findet sich sicherlich auch bei der Umsetzung des C Language Bindings.

Für ein Exeption Handling bietet REXX die Möglichkeiten diese über Umgebungsvariablen abzubilden. Denkbar wäre auch, wie beim C Mapping, die Exception auf einen Struct, abbzubilden, der dann in einheitlicher Weise jeder Methode als ein drittes Argument per Referenz übergeben wird, oder auf eine globale Variable die innerhalb des Servants oder Clients dann Gültigkeit besitzt, und somit global zu den Methoden ist.
REXX bietet die Möglichkeit der Schachtelung von  Umgebungen und deren Umgebungsvariablen.
 

Auch für REXX gibt es eine Objektorientierte Erweiterung, oder besser: Aufbauend auf dem klassischen REXX ist Objekt-REXX entstanden, die eine ähnliche Abwärtskompatibilität zum klassischen REXX bietet, wie es analog mit C und C++ der Fall ist.
Einige Objektorientierte Eigenschaften verwenden zu können wäre von Vorteil: Auf der einen Seite für die Bildung von Servants, von denen man vielleicht eine größere Anzahl Instanzen bilden muß, zum anderen für die später erwähnten Pseudoobjekte.
 

    7.2  Das SAA-API, Statische Umsetzung
 
Der REXX-Interpreter selber liegt in Form einer dynamisch linkbaren Datei vor. Potentiell jede Applikation kann diesen einbinden und verwenden. Er ist voll reentrant und unterstützt, daß im selben Prozess mehrere REXX-Prozeduren auf unterschiedlichen Threads laufen können. Über Einbinden einer bereits bestehenden Headerdatei Rexx.h kann man diesen Interpreter innerhalb von  C, C++ verwenden.

Teil von REXX ist ein API genannt SAA. Dieses beschreibt ein Interface, zwischen dem Rexxinterpreter und anderen comipilierten Programmen
Die Spezifikation unterteilt sich in mehrere Unterbereiche:


Subcommand Handler
Diese Sektion beschreibt den Subcommand Handler, der es einer Applikation erlaubt, Kommandos, die sich in einem RexxSkript befinden, einzuschließen, und sie selber auszuführen.
Es wird davon ausgegangen, daß eine Applikation den RexxInterpreter gestartet hat, dieser also im gleichen Adressraum läuft wie der Prozeß. Nach Laden eines Rexxskriptes, können die im Skript enthaltenen Unterfunktionen dann vom umgebenden Programm ausgeführt werden. Aus Sicht des Interpreter ist dieses Programm eine externe Umgebung. Ruft der Interpreter den Subkommandohandler auf, und übergibt ihm das Kommando als Parameter so ist das Handle in der Lage das Kommando auszuführen. dieser sieht so aus:

    APIRET APIENTRY handler(
        PRXSTRING command,
        PUSHORT flags,
        PRXSTRING returnstring, )
 

RexxRegisterSubcomExe()
Diese Funktion soll ein Subkommando mit dem Interface registrieren. Dieser SubkommandoHandler, wie oben erwähnt , muß sich innerhalb des Codes des aufrufenden Programmes befinden. Nach dieser Registrierung kann eine Rexx interpreter dieses Subkommando dann ausführen, indem der Subkommandohandle, der sich ja im aufrufenden Programm befindet, aufgerufen wird, und diesem der Name des Subkommandos übergeben wird.

ExternalFunctionHandler
Diese Sektion beschreibt einen externen Funktionen Handler, der die Sprache erweitern kann, indem er externe Funktionen in anderen Sprachen schreiben läßt!!
 
 

Betrachtet man die Möglichkeiten des Saa, so sind die Bedingungen für eine Realisierung wie in der vorgestellten TCL-Lösung Rapid Corba Server Development gegeben:

Auf der Serverseite kann die Implementierung in REXX geschrieben werden, und in einem Interpreter ablaufen  der sich innerhalb eines Servers befindet, der in einer anderen Sprache realisiert ist. Genau diesen Vorteil hat sich die vorgestellte Lösung zu Nutze gemacht, daß das C++ Language Binding eine gute Grundlage bilden kann, da es von fast allen ORB schon unterstützt wird. Ein Skript mit den REXX-Subroutinen ist in einen REXX-interpreter ladbar.


Abbildung4 : Die Realisierung eines statischen Servers


Wie erwähnt wurde, gibt es die Möglichkeit in REXX, Funktionen im Format einer DLL über RXFuncadd() einzubinden, und zu benutzen als handele sich um ein Rexx eigene Kommandos. Sofern es also möglich ist, aus der in C++ vorliegenden Stubdatei eine dynamische Bibliothek zu erzeugen, könnte man auf die nunmehr in diesem Stub befindlichen Funktionen aus Rexx beschriebener Weise zugreifen.
Eine andere Alternative, ebenfalls aus dem Saa Packet stammend, scheint der External Function Handler zu sein, mit dem man nach der Registrierung der externen Funktion durch rexxregisterfunctionexe() diese dann auch innerhalb REXX verwenden kann.


Abbildung5 : Die Realisierung eines statischen Clienten
    7.3  Pseudoobjekte
 
Rekapitulieren wir noch einmal den Vorgang beim dynamischen Methodenaufruf, wie er in Kap6 aufgeführt wurde. Um einen Zugang zu CORBA zu bekommen, mußte man zunächst einen Zugang zu einem ORB erlangen. Dazu mußte ein sogenanntes ORB-Objekt erzeugt und initialisiert werden. Dafür gibt es in einer objektorientierten Programmiersprache eine Art Klassenmethode, die zu den Pseudoobjekten gehört. .
Eingangs wurde auch erwähnt, daß es sich bei den Objekten ORB und BOA um Pseudoobjekte handelte.
Hier stellt sich die Frage, wie mit Pseudoobjekten umgegangen werden soll.
 
  • "Pseudoobjekte sind Objekte, die im lokalen Adressraum der verwendeten Programmiersprache liegen, und genauso, wie normale CorbaObjekte behandelt werden, was bedeutet, daß aus Sicht des Programmierers kein Unterschied in den Methodenaufrufen entfernter und lokaler Objekte zu erkennen ist."
  • "Ein Pseudoobjekt ist ein Objekt, das der ORB direkterweise erzeugt. Der ORB selber ist auch ein Pseudoobjekt.
  • "Eine Referenz auf eine Instanz des Pseudoobjektes ORB erhält man, indem man den Aufruf der Methode Orb-init() ausführt
  • "Pseudo Objekte sind Sprachenspezifische Objkte, ein solches Orbobjekt ist nicht notwendigerweise entfernt Es ist typischerweise ein Prozess-lokales programmiersprachliches Konstrukt. und ist damit Beschränkungen unterlegen: einerseits, daß es nicht im IR repräsentiert ist, andererseit auf eine offentliche abstrakte Klasse gemappt wird, die keine anderen Klassen erweitert, (oder in JAVA von Interfaces erbt).
  •   


    Abbildung6 : Der Zusammenhang mit den Pseudoobjekten

     

    Es stellt sich die Frage, wie man ein solches Pseudoobjekt, das es für C++ gibt, für REXX verfügbar machen kann. Für den in Kap 7.2 gezeigten statischen Ansatz, bildet das Language Binding in REXX eine Schicht, die oberhalb des Stubs liegt. Der Stub enthält konzeptionell die Instanz eines ORBs. Der ORB findet sich in Form von in den Stub miteinkompilierten Funktionen wieder.
    Für diesen Ansatz muß lediglich das Problem gelöst werden, wie die Umwandlung der REXX Argumente in C++ vollzogen wird, und wie man dies automatisieren kann.


    Abbildung7 :

     

    Die Dynamische Seite

    Betrachtet man eine Reihe von ORBs, so stellt man fest, daß sie nur einige wenige Language Bindings unterstützen. Bei manchem ORB scheint die Verbindung der Implementierung des ORB eng verbunden mit dem angebotenen Language Binding.

    Aus der Beschreibung zum COMBAT-Paket, das das oben genannteTCL-Binding enthält, läßt sich entnehmen, daß es auf theoretisch jedem ORB läuft, der ein C++ Sprachbinding anbietet. "Combat ist ein glue-package, geschrieben in C++, und hat Zugang zu Merkmalen, die nicht verfügbar sind in TCL"

    Auch wenn man die Pseudoobjekte, oder besser die Teile, die sich eng an die Implementierung des ORB anlehnen  in ihrer Programmiersprache beläßt, so muß das DII nicht unbedingt in C++ geschrieben werden, wenn man einerseits den ORB-internen Protokollmechanismus kennt, sofern dieser abweichend vom IIOP ist, oder wie bei einigen anderen Lösungen beschrieben, die IIOP Requests selber erzeugt. Da dies mit einem für Standardverbindungen in TCP/IP tauglichen Socket geschehen kann, könnte man das DII tatsächlich in Rexx schreiben.


    Abbildung8 :

     
     
     
     
     
     
     
     

    Literaturverzeichnis:
     

    [1]    John Siegel "Corba3-fundamentals and programming"-OMG-Press 2000
    [2]    OMG-C Language Mapping Spec-Orbos99-07-35
    [3]    OMG-C++ Language Mapping Spec-Orbos99-07-41
    [4]    OMG-Corba Specification 2.3-Orbos99-10-07
    [5]    Frank Pilhofer-"A Corba Language Mapping"-7th Usenix Tcl/Tk Conference
    [6]    Frank Pilhofer-"Combat"-http//www.informatik.uni-frankfurt.de/~fp/Tcl/Combat
    [7]    Jason Brazile-"Rapid Corba Server Development"-7th Usenix Tcl/Tk Conference
    [8]    "Perl Binding"-System Management Hewlett Packard
    [9]    Orfali/ Harkey-"Corba Programming with JAVA and CORBA"-Wiley Press 1998
    [10]  "MICO is CORBA, an open source CORBA 2.3 implementation"-Dokumentation zum Orb-http://www.mico.org
    [11]  Christensen-"the regina Rexx interpreter"-beiligende Dokumentation-8.2000
    [12]  Pilhofer/Merkle-"Corba-Mapping für Skriptsprachen"-Ix Magazin 4.1999