//Java
...
_ObjectRef objRef = ...
Request request = objRef._request("test_method");
request.invoke();
...
Wie man an diesem Beispiel sieht, muß für den dynamischen Aufruf lediglich ein
Pseudo-Objekt der Klasse Request erzeugt werden, in dem schließlich
die invoke()-Methode aufgerufen wird. Wie verfährt man nun mit der
Übergabe von Parametern an den Funktionsaufruf? Es erscheint sinnvoll, etwas
wie eine Parameterliste zu erstellen, in der die einzelnen Argumente zusammen
mit ihrer Typinformation und ihrem Aufrufmodus (in, out, inout)
enthalten sind. Genau dies wird durch die Klassen NVList und
NamedValue bereitgestellt. Wir wollen zunächst am Beispiel einer
Java-Implementation den dynamischen Funktionsaufruf von
//Java
...
_ObjectRef oRef = ...
Request request = oRef._request("test_method");
//NVList fuer Request erzeugen
NVList arglist = request.arguments();
//Argumente in NVList einfuegen
Any arg1 = new Any(),
arg1.insertLong(42);
arglist.add_value("iarg", arg1, _CORBA.ARG_IN);
Any arg2 = new Any();
arg2.insertString("bla");
arglist.add_value("sarg", arg2, _CORBA.ARG_IN);
request.invoke();
request.extractOutParams();
String res = request.result();
...
![]() |
Wie man erkennen kann, werden die Argumente direkt in die Liste vom Typ NVList eingefügt, wo sie in einem NamedValue gespeichert werden (dies ist auch der Rückgabetyp der add_value()-Operation). Der NamedValue selbst tritt lediglich dann explizit in Erscheinung, wenn Parameter bearbeitet oder extrahiert werden sollen, Dies ist zum Beispiel bei out- und inout-Werten nach dem Funktionsaufruf der Fall. Wie beim Interface Repository und Naming Service wird auch die Implementation des DII in Corba 2.0 dem ORB-Hersteller überlassen, die Standard-Konformität jedoch durch die Spezifikation der Objekte in pseudo-IDL sichergestellt. Diese wollen wir als Dokumentation der Funktionalität der Klassen NVList und NamedValue betrachten:
//IDL
module CORBA {
...
pseudo interface NamedValue {
readonly attribute Identifier name;
readonly attribute any value;
readonly attribute Flags flags ;
};
pseudo interface NVList {
readonly attribute unsigned long count;
NamedValue add_item(
in Identifier item_name,
in Flags flags );
NamedValue add_value(
in Identifier item_name,
in any val,
in Flags flags );
NamedValue item(in unsigned long index) raises (Bounds);
NamedValue remove(in unsigned long index) raises (Bounds);
};
...
};
Es gilt also Folgendes: Einer NVList kann durch den Aufruf der Methode
add_item() oder add_value() ein Parameter hinzugefügt werden,
der mittels der Methode item() abgefragt werden kann. Der so erhaltenen
NamedValue läßt sich dann durch Abfrage der Attribute name,
value und flags abfragen. Verändern läßt sich ein bereits
eingefügter NamedValue nicht, er muß mittels NVList::remove() aus
der Liste entfernt und durch einen neuen ersetzt werden. Wir wollen nun noch einen Blick auf die verschiedenen Aufrufoptionen eines dynamisch erzeugten Requests werfen. Dazu betrachten wir zunächst wieder die im Standard festgelegte IDL-Definition:
// IDL
pseudo interface Request {
readonly attribute Object target;
readonly attribute Identifier operation;
readonly attribute NVList arguments;
readonly attribute NamedValue result;
readonly attribute Environment env;
attribute Context ctx;
Status invoke();
Status send_oneway();
Status send_deferred();
Status get_response();
boolean poll_response();
};
Wie man sieht, befinden sich unter den Methoden neben dem normalen
invoke()-Aufruf weitere Operationen, die einen asynchronen Aufruf
unterstützen. Bei dieser Aufrufsart wird der Request zunächst via
send_deferred() auf den Server übertragen. Später können dann
durch Aufruf der Methode poll_response() und get_response() der
Rückgabewert und die inout/out-Parameter ausgelesen werden, um
diese weiter zu verarbeiten. Auf diese Weise ist es z.B. möglich, die
Wartezeit bis zur Ausgabe des Ergebnisses des Methodenaufrufs vom Server
durch weitere Aktionen auf Seiten des Clients auszufüllen oder mehrere
konkurrierende Methodenaufrufe zu starten und das schnellste Ergebnis
auszuwerten. Enthält der Funktionsaufruf keinen Rückgabewert oder
inout/out-Parameter, so bietet sich die Verwendung von
send_oneway() an. Bei dieser Aufrufsart wartet der Client nicht auf
das Ende der Operation, wodurch ihm jedoch auch der Erfolg des Aufrufs im
unklaren bleibt.