Przed startem programu należy uruchomić usługę nazewniczą:
po_cos_naming
Usługa ta zwróci IOR, który należy ustawić jako wartość zmiennej środowiskowej POLYORB_DSA_NAME_SERVICE, np.:
export POLYORB_DSA_NAME_SERVICE=corbaloc:iiop:1.2@150.254.30.38:40941/NameService/000000024fF0000000080000000
Specyfikacja pakietu (rci.ads):
package RCI is pragma Remote_Call_Interface; type Wpis is record numer: Positive; nazwa: String(1..10); end record; procedure Wstaw(p: in Wpis); function Nazwa(n: in Positive) return String; end RCI;
Implementacja pakietu (rci.adb):
with Ada.Text_IO; use Ada.Text_IO; package body RCI is Max: constant Positive := 100; wpisy: array (1..Max) of Wpis; procedure Wstaw(p: in Wpis) is begin wpisy(p.numer) := p; -- Put_line(Positive'Image(p.numer) & ". " & p.nazwa); end; function Nazwa(n: in Positive) return String is begin return wpisy(n).nazwa; end; end RCI;
Przykład wywołania zdalnej procedury (rcall.adb):
with Ada.Text_IO, RCI; use Ada.Text_IO; procedure rcall is p: RCI.Wpis; begin p.numer := 1; p.nazwa(1..5) := "Darek"; Put_line(p.nazwa); RCI.Wstaw(p); Put_line(RCI.Nazwa(1)); end rcall;
Opis konfiguracji (conf1.cfg):
configuration conf1 is pragma Boot_Location ("tcp", "localhost:5678"); pragma Starter (none); client, server: Partition; procedure rcall is in client; begin server := (RCI); end conf1;
Sposób kompilacji:
gnatdist conf1.cfg
Uwaga: nazwa pliku musi być taka sama jak nazwa opisanej w nim konfiguracji.
Pakiet zawiera tylko specyfikację i musi być skategoryzowany jako Pure (types.ads).
package Types is pragma Pure; Max_Name: constant Positive := 10; type Wpis is record numer: Positive; nazwa: String(1..Max_Name); end record; end Types;
Proszę zwrócić uwagę na obsługę wyjątków, np. wywołując procedurę zdalną z jakąś dużą wartością w polu numer rekordu-parametru (rcall.adb — wersja 2):
with Ada.Text_IO, RCI, Types; use Ada.Text_IO; procedure rcall is p: Types.Wpis; begin p.numer := 150; p.nazwa(1..5) := "Darek"; Put_line(p.nazwa); RCI.Wstaw(p); Put_line(RCI.Nazwa(1)); end rcall;
Różnica jest w kodzie występuje tylko w specyfikacji (rci.ads — wersja asynchroniczna):
with Types; use Types; package RCI is pragma Remote_Call_Interface; procedure Wstaw(p: in Wpis); pragma Asynchronous(Wstaw); function Nazwa(n: in Positive) return String; end RCI;
Dodatkowy pakiet kategorii Remote_Call_Interface (callback.ads)
package Callback is pragma Remote_Call_Interface; procedure Return_key(key: in Positive); end Callback;
i jego przykładowa implementacja callback.adb.
W przypadku poniższego wywołania procedura zwrotna wiązana jest statycznie, tzn. indentyfikowana jest jednoznacznie już w kodzie źródłowym i znana kompilatorowi (rci.adb — wersja z wywołaniem zwrotnym):
with Ada.Text_IO; use Ada.Text_IO; with Callback; package body RCI is Max: constant Positive := 100; wpisy: array (1..Max) of Wpis; procedure Wstaw(p: in Wpis) is begin wpisy(p.numer) := p; Put_line(Positive'Image(p.numer) & ". " & p.nazwa); Callback.Return_key(p.numer); end; function Nazwa(n: in Positive) return String is begin return wpisy(n).nazwa; end; end RCI;
W opisie konfiguracji pakiet procedur zwrotnych jest w partycji klienta (conf6.cfg):
configuration conf6 is pragma Boot_Location ("tcp", "localhost:5678"); pragma Starter (none); client, server: Partition; procedure rcall is in client; begin server := (RCI); client := (Callback); end conf6;
Do procedury zdalnej przekazywany jest wskaźnik (zdalny) na procedurę zwrotną. Typ wskaźnikowy musi być zdefiniowany w jednostce kategorii Remote_Call_Interface (callback.ads — def. zdal. wsk. na proc.)
package Callback is pragma Remote_Call_Interface; procedure Return_key(key: in Positive); type Callback_Procedure is access procedure (key: in Positive); end Callback;
Przykład wywołania procedury zdalnej (rcall.adb — przekazanie wsk. na proc. zwrotną):
with Ada.Text_IO, RCI, Types; use Ada.Text_IO; with Callback; procedure rcall is p: Types.Wpis; begin p.numer := 1; p.nazwa(1..5) := "Darek"; Put_line(p.nazwa); RCI.Wstaw(p, Callback.Return_key'access); Put_line(RCI.Nazwa(1)); end rcall;
Przykład wywołania procedury zwrotnej (rci.adb — wywołanie z wiąz. dynamicz.):
with Ada.Text_IO; use Ada.Text_IO; package body RCI is Max: constant Positive := 100; wpisy: array (1..Max) of Wpis; procedure Wstaw(p: in Wpis; cb_proc: in Callback_Procedure) is begin wpisy(p.numer) := p; Put_line(Positive'Image(p.numer) & ". " & p.nazwa); cb_proc(p.numer); end; function Nazwa(n: in Positive) return String is begin return wpisy(n).nazwa; end; end RCI;
Przykład definicji zdalnego obiektu (remote_key.ads):
with Types; use Types; package Remote_Key is pragma Remote_Types; type Remote_Key_Type is new Key_Type with private; procedure Return_key(key: access Remote_Key_Type; value: in Positive); type Remote_Key_Reference is access all Remote_Key_Type'Class; -- pragma Asynchronous(Remote_Key_Reference); private type Remote_Key_Type is new Key_Type with null record; end Remote_Key;
Implementacja procedury Return_key sprowadza się do podstawienia wartości parametru w odpowiednie pole rekordu i wyświetlenia komunikatu (remote_key.adb)
Definicja typu Remote_Key_Type oparta jest na definicji rekordu znakowanego Key_Type w pakiecie Types (types.ads z typem znakowanym, types.adb).
Sam obiekt typu Remote_Key_Type tworzony jest w normalnym pakiecie Remote_Object (remote_object.ads).
Przykłady użycia obiektu zdalnego są w plikach (rcall.adb z przkaz. wsk. na zdal. obiekt , rci.ads z odniesieniem do zdal. obiektu, rci.adb z odniesieniem do zdal. obiektu)
Konfiguracja uwzględnia fakt, że może być wielu klientów. Wyodrebnione zostały 2 rodzaje partycji client — jedna z zasadniczą procedurą główną (i tym samym boot serwerem), a druga z alternatywną procedurą główną (conf7.cfg):
configuration conf7 is pragma Boot_Location ("tcp", "localhost:5678"); pragma Starter (none); client1, client2, server: Partition; for server'Termination use Global_Termination; procedure rcall is in client1; for client1'Termination use Deferred_Termination; for client2'Main use rcall; for client2'Termination use Local_Termination; -- for client2'Allow_Light_PCS use False; begin server := (RCI); -- client1 := (Callback); -- client2 := (Callback); end conf7;