PRG: Corba - uvod pro neznale


To ucto-dev-l@pinknet.cz
From Petr Ferschmann <petr@ferschmann.cz>
Date Sun, 24 Mar 2002 11:45:36 +0100
Organization Petr Ferschmann

Zdravicko,

Zakladem komunikace bude CORBA. Corba je vlastne neco jako RPC (Remote
Procedure Call), ale podporuje OOP. Mohu tedy pouzivat objektove jazyky.
Velice elegantne se pouziva  a je i docela rychla. Zde bych Vam rad udelal
jednoduchy uvod do corby.

Zakladem vseho je IDL (Interface Definition Language). Popis rozhrani. 

Zde je ukazka:

-- CUT HERE --

interface Account {
  void deposit( in unsigned long amount );
  void withdraw( in unsigned long amount );
  long balance();
};
	    
interface Bank {
    Account create ();
};

-- CUT HERE --

Interface je neco jako class v C++. Takze mame zde dva objekty. Banka a ucet.
Banka umoznuje vytvorit novy ucet a vratit na nej "vzdaleny ukazatel".

Pomoci IDL kompilatoru prelozite tento program a on vygeneruje pomocne kusy
kodu. Diky tomuto generovani je vse tak krasne rychle. 

Nyni ukazka klienta:

-- CUT HERE --
// Includovaci hlavicky jsou zavisle na pouzite CORBE.
#include <ORBitservices/CosNaming.hh>

int
main (int argc, char *argv[])
{
  CORBA::ORB_var orb = CORBA::ORB_init (argc, argv, "orbit-local-orb");

  /* kontrola parametru */
  if( argc == 0 ) {
    printf( "Musite zadat jeden parameter IOR serveru\n" );
    return( 1 );
  }

 /* z parametru dostaneme "vzdaleny ukazatal" a vytvorime si z nej
    objekt */
 CORBA::Object_var obj = orb->string_to_object( argv[1] );

  /* provedeme kontrolu zda je ukazatel platny */
  if (CORBA::is_nil (obj)) {
    printf ("oops: bind to Bank failed\n");
    exit (1);
  }

  /* ted uz provedeme jen pretypovani z obecneho objektu na Bank */
  Bank_var bank = Bank::_narrow (obj);

  /*
   * Vytvorime si ucet - vypada to jako bychom volali mistni objekt.
   * ale zdani klame - toto vyvola volani po siti :-)
   */

  Account_var account = bank->create ();

  /*
   * Provedeme nejake operace a vypiseme vysledek
   */
  account->deposit (700);
  account->withdraw (450);

  printf ("Balance is %ld.\n", account->balance ());

  return 0;
}

-- CUT HERE --

Jak vidite programatorovi je pozdeji jiz uplne jedna zda objekt bezi ve 
stejnem programu  nebo je na druhem konci sveta. Pouziva se to krasne.

Tak ted jeste server:


-- CUT HERE --

/*
 * Implementace uctu. V CORBE je zvykem implementace
 nazvat jako neco_impl.
 */

class Account_impl : virtual public POA_Account
{
public:
  Account_impl () {
    bal = 0;
  }

  void deposit (CORBA::ULong amount) {
      bal += amount;
  }
  void withdraw (CORBA::ULong) {
      bal -= amount;
  }
  CORBA::Long balance () {
      return( bal );
  }

private:
  CORBA::Long bal;
};

/*
 * Implementace Banky
 */

class Bank_impl : virtual public POA_Bank
{
public:
  Account_ptr create ();
};

Account_ptr Bank_impl::create ()
{
  /*
   * Vytvorime novy ucet
   */

  Account_impl * ai = new Account_impl;

  /*
   * Nyni ziskame z tohoto objektu vzdaleny ukazatel
   */

  Account_ptr aref = ai->_this ();
  assert (!CORBA::is_nil (aref));

  /*
   * Vratime vzdaleny ukazatel
   */

  return aref;
}

int
main (int argc, char *argv[])
{
  /*
   * Nainicializujeme CORBU
   */
  CORBA::ORB_var orb = CORBA::ORB_init (argc, argv, "orbit-local-orb");

  /*
   * Ziskame instanci na POA - ridi destrukci objektu kdyz jiz nejsou potreba
   */
  CORBA::Object_var poaobj = orb->resolve_initial_references ("RootPOA");
  PortableServer::POA_var poa = PortableServer::POA::_narrow (poaobj);
  PortableServer::POAManager_var mgr = poa->the_POAManager();

  /*
   * Vytvorime banku
   */
  Bank_impl * micocash = new Bank_impl;

  /*
   * Aktivujeme banku - predame POA
   */
  PortableServer::ObjectId_var oid = poa->activate_object (micocash);
  CORBA::Object_var object = poa->id_to_reference(oid);

  /* Zapiseme vzdaleny ukazatel do retezce a vytiskneme */
  CORBA::String_var ior = orb->object_to_string( object );
  printf( "%s\n", ior.in() );

  /*
   * Nyni zaktivujeme POA a uz bezime.
   */
  mgr->activate ();
  orb->run();

  /*
   * Ukoncime program
   */
  poa->destroy (TRUE, TRUE);
  delete micocash; /* prohlasime bankrot banky :-) */

  return 0;
}
-- CUT HERE --

Po spusteni server vypise vzdaleny ukazatel:
IOR:010000000d00000049444c3a42616e6b3a312e300000000001000000caaedfba5000000001
010000270000002f746d702f6f726269742d666572732f6f72622d333936353034393434363934
39393536383500000000000018000000000000009b97779861da684001000000a2ef4a4d0a8a86
dd


Ten obsahuje jmeno serveru, port a dalsi informace. Toto staci pro volani 
vzdalenych objektu. 


Pokud se Vam zda predavani IOR pres prikazovy radek neprijemne tak vezte, ze
existuje tzv. NamingService kam se server pripoji, rekne ze se jmenuje Bank a 
ulozi zde svoji IOR. Klient pak zna NamingService a zepta se na Bank a ziska 
IOR.





-- 

                                  Petr "Fers" Ferschmann

 -=[  petr@ferschmann.cz  ]==[ http://petr.ferschmann.cz/ ]=-
-=[ Koukni na http://www.postcard.cz/ ]==[ +420 604/781 009 ]=-

GPG Fingerprint:
[83B0 6378 7A9D D993 035E  60BD FEEC F665 D2C8 1B9A]

-------------------------- ucto-dev-l@pinknet.cz ------------------------
Konference o vyvoji ucetnictvi                       http://ucto.linux.cz/


Partial thread listing: