CORBA with C++

CORBA with C++:
CAMAC client sample programCORBA with C++

CORBA with C++ The following program is a test client (deducted from omniORB2's echo example) which compiles under Windows (WIN32) or Linux (Redhat 6.0). You need to download and install the omniORB2 package in order to build the test client. Please read the appropriate instruction file(s) delivered with the package. After a successful completion of the program building process you should be able to connect to one of the 7 CAMAC servers if you know its name. The omniORB2 COS (Common Object Services) naming server "omniNames" is running on pc303.psi.ch and using port 900. The main purpose of COS is to deliver an IOR (Interoperable Object Reference, which ia a non human readable ASCII string of more than 100 chars and generated by each CORBA object when it is started the first time) allowing the CORBA client to find and access its desired remote object.



1) file CamCoStr.idl:
=====================

interface CamCoStr
{
   string cacoStr(in string inStr);
};


2) file CamCoStr.h:
===================

#include <omnithread.h>
#include "CamCoStr.hh" // *.hh files are generated by the idl compiler.

class CamCoStr_i : public _sk_CamCoStr //_sk_CamCoStr is the skeleton
{
private:
   char outStr[2048];
   omni_mutex mutex;
public:
   CamCoStr_i(const char * theName);
   virtual ~CamCoStr_i();
   virtual char * cacoStr(const char * inStr)
           throw(CORBA::SystemException);
};


3) file CamCoStr.c:  (This is the CORBA object's implementation.)
===================

#include "CamCoStr.cc"
#include "docamac.h"

// define the constructor

CamCoStr_i::CamCoStr_i(const char *port)
{
   IniCamac((char *)port);
}

// define the destructor

CamCoStr_i::~CamCoStr_i()
{
}

// Here is the actual implementation of cacoStr.

char *CamCoStr_i::cacoStr(const char *inStr)
     throw(CORBA::SystemException)
{
   mutex.lock();
   DoCamac((char *)inStr,(char *)outStr);
   mutex.unlock();
   return(outStr);
}


4) file client.cc:
==================

/*
client program for testing CORBA camac server.
compiled by Urs Rohrer (PSI), May 1999
used CORBA implementation: omniORB2 (for C++)
(see http://www.uk.research.att.com/omniORB/omniORB.html)
*/

#ifdef WIN32
#include <windows.h>
#else // Redhat Linux Version 6.0
#include <stdio.h>
#include <stdlib.h>
#endif
#include <iostream.h>
#include <string.h>
#include "CamCoStr.hh"

static CORBA::Object_ptr getObjectReference(CORBA::ORB_ptr orb, char *myname);
static int InitializeCORBA(char *, CamCoStr_var *);
static int CORBAsend(CamCoStr_var, char *, char *);
void Help(void);

int main(int argc, char **argv)
{
  if (argc != 2)
  {
     cout << "Usage: Client Server_Name" << endl; // e.g: client pcxyz
     return 0;
  }

  CamCoStr_var cacostrVar;		       ////////////
  if (InitializeCORBA(argv[1],&cacostrVar))    ////////////
  {
     char   command[100], answer[2000];
     int    ok = 1;
     while (ok > 0)
     {
       cout << "Enter command [ ? for help, EXIT for quit ] : " << flush;
       cin.getline(command,100);
       if (strlen(command) != 0)
       {
         if (strcmp(command,"?") == 0)
	    Help();
         else if (strcmp(command,"EXIT") == 0)
            ok = 0;
         else
         {
	    if (CORBAsend(cacostrVar, command, answer) == 1) ////////////
	    {
               cerr << "server returned: "; 
               cerr << answer << endl;
	    }
	    else
	    {
               cerr << "error" << endl;
	       cin.ignore(80,'\n');
	       ok = 0;
	    }
         }
       }
     }
  }
  return 0;
}

static int CORBAsend(CamCoStr_var cacostrVar, char *sendbuf, char *recbuf)
{
  int retval;

// Call the remote object

  try
  {
#ifdef WIN32
     strcpy(recbuf,(char *)cacostrVar->cacoStr((CORBA::String_var)sendbuf));
#else // Redhat Linux Version 6.0
     strcpy(recbuf,(char *)cacostrVar->cacoStr(sendbuf));
#endif
     retval = 1;
  }
  catch( CORBA::COMM_FAILURE & ex)
  {
     cerr << "Caught system exception COMM_FAILURE" << endl;
     cerr << "We seem to be missing a server object" << endl;
     cerr << "Make sure that (1) the server is running and" << endl;
     cerr << "(2) that the ior.out file that server writes" << endl;
     cerr << "out is accessible from this client's" << endl;
     cerr << "present working directory" << endl;
     retval = 0;
  }
  catch( omniORB::fatalException & ex)
  {
     cerr << "Caught omniORB2 fatalException. This is a bug in omniORB" << endl;
     retval = 0;
  }
  return retval;
}

static int InitializeCORBA(char *p1, CamCoStr_var *var)
{
   char key[100], name[20], port[20];
   int  argc = 3;			// dummy
   char *argv[] = {"","",""};		// dummy
   
// initialize CORBA object:

   CORBA::ORB_ptr orb           = CORBA::ORB_init(argc,argv,"omniORB2");
   CORBA::BOA_ptr boa           = orb->BOA_init(argc,argv,"omniORB2_BOA");
   CORBA::Object_var obj        = getObjectReference(orb,p1);
   if (obj == CORBA::Object::_nil())
      return 0;

   CamCoStr_var cacostrVar      = CamCoStr::_narrow(obj);
   *var = cacostrVar;
   return 1;
}

static CORBA::Object_ptr getObjectReference(CORBA::ORB_ptr orb, char *myname)
{
  CosNaming::NamingContext_var rootContext;
  
  try
  {
    // Obtain a reference to the root context of the Name service:
    CORBA::Object_var initServ;
    initServ = orb->resolve_initial_references("NameService");

    // Narrow the object returned by resolve_initial_references()
    // to a CosNaming::NamingContext object:
    rootContext = CosNaming::NamingContext::_narrow(initServ);
    if (CORBA::is_nil(rootContext)) 
    {
        cerr << "Failed to narrow naming context." << endl;
        cin.ignore(80,'\n');
        return CORBA::Object::_nil();
    }
  }
  catch(CORBA::ORB::InvalidName& ex)
  {
    cerr << "Service required is invalid [does not exist]." << endl;
    cin.ignore(80,'\n');
    return CORBA::Object::_nil();
  }
  catch(...)
  {
    cerr << "COS Naming Service failed [not up ?]." << endl;
    cin.ignore(80,'\n');
    return CORBA::Object::_nil();
  }


  // Create a name object, containing the name "myname":

  CosNaming::Name name;
  name.length(2);

  name[0].id   = (const char*) myname;
  name[0].kind = (const char*) "";
  name[1].id   = (const char*) myname;
  name[1].kind = (const char*) "Object";
  
  CORBA::Object_ptr obj;
  try
  {
    // Resolve the name to an object reference, and assign the reference 
    // returned to a CORBA::Object:
    obj = rootContext->resolve(name);
  }
  catch(CosNaming::NamingContext::NotFound& ex)
  {
      // This exception is thrown if any of the components of the
      // path [contexts or the object] aren't found:
      cerr << "Context not found." << endl;
      cin.ignore(80,'\n');
      return CORBA::Object::_nil();
  }
  catch (CORBA::COMM_FAILURE& ex)
  {
    cerr << "Caught system exception COMM_FAILURE, unable to contact the "
         << "naming service." << endl;
    cin.ignore(80,'\n');
    return CORBA::Object::_nil();
  }
  catch(omniORB::fatalException& ex)
  {
    throw;
  }
  catch (...)
  {
    cerr << "Caught a system exception while using the naming service."<< endl;
    cin.ignore(80,'\n');
    return CORBA::Object::_nil();
  }
  return obj;
}

void Help(void)
{
 cout << "Sample Server Version 1.00: Legal commands are:\n\
 -------------------------------------------------------------------------\n\
 | desired Action   | Input           | Receive (ok)      | or Error     |\n\
 -------------------+-----------------+-------------------+---------------\n\
 | ReadAllDevices   | RALL            | *RALL* <list>     | *RALL* 0     |\n\
 | ReadAllDevices   | RAL2            | *RAL2* <list>     | *RAL2* 0     |\n\
 | ReadAllDacs      | ALLD            | *ALLD* <list>     | *ALLD* 0     |\n\
 | WriteDAC         | WDAC XYZ nnn    | *WDAC* XYZ= nnn   | *WDAC* error |\n\
 | WriteDAC&Wait    | WDAW XYZ nnn    | *WDAW* XYZ= nnn   | *WDAW* error |\n\
 | ReadDAC          | RDAC XYZ        | *RDAC* XYZ= nnn   | *RDAC* error |\n\
 | ReadADC          | RADC XYZ        | *RADC* XYZ= nnn   | *RADC* error |\n\
 | ReadCamacDac     | RCAD XYZ f      | *RCAD* nnn        | *RCAD* error |\n\
 | WriteCamacDac    | WCAD XYZ f nnn  | *WCAD* nnn        | *WCAD* error |\n\
 | DoReadCamac      | RCAM N A F      | *RCAM* sta nnn    | *RCAM* error |\n\
 | DoWriteCamac     | WCAM N A F nnn  | *WCAM* sta        | *WCAM* error |\n\
 | DoControlCamac   | CCAM N A F      | *CCAM* sta        | *CCAM* error |\n\
 | GetDeviceName    | DEVN nnn        | *DEVN* nnn= XYZ   | *DEVN* error |\n\
 | DeviceParameter  | DEVP nnn        | *DEVP* <3par>     | *DEVP* error |\n\
 | DeviceParameter2 | DEPA nnn        | *DEPA* <17par>    | *DEPA* error |\n\
 | DeviceParameter3 | DEPB nnn        | *DEPB* <4par>     | *DEPB* error |\n\
 -------------------+-----------------+-------------------+---------------\n\
 --- press <Enter> key for more ---" << flush;
 
 cin.ignore(80,'\n');

 cout << "\
 -------------------------------------------------------------------------\n\
 | desired Action   | Input           | Receive (ok)      | or Error     |\n\
 -------------------+-----------------+-------------------+---------------\n\
 | ReserveCrate     | RESC            | *RESC* 1          | *RESC* 0     |\n\
 | FreeCrate        | FREE            | *FREE* 1          |              |\n\
 | NewDeviceList    | NEWL            | *NEWL* 1          | *NEWL* 0     |\n\
 | GetPageIndex     | PIND nnn        | *PIND* nnn        | *PIND* error |\n\
 | GetNumberOfPages | NPAG            | *NPAG* nnn        |              |\n\
 | ReadOnePage      | RPAG nnn        | *RPAG* nnn <list> | *RPAG* 0     |\n\
 | SwitchOnCombis   | SWON            | *SWON* nnn        |              |\n\
 | SwitchOnCombi    | SWCO XYZ        | *SWCO* XYZ 1      | *SWCO* XYZ 0 |\n\
 | SwitchOffCombi   | SWOF XYZ        | *SWOF* XYZ 1      | *SWOF* XYZ 0 |\n\
 | ClearScalers     | CLSC sn s1 s2   | *CLSC*            | *CLSC* error |\n\
 | ReadScalers      | RDSC sn s1 s2   | *RDSC* nnn mmm    | *RDSC* error |\n\
 | ReadClAllScalers | RCAS n          | *RCAS* <6rates>   | *RCAS* error |\n\
 | Shutdown         | EXIT            |                   |              |\n\
 | Help info        | ?               | these help frames |              |\n\
 -------------------------------------------------------------------------\n"
 << flush;
}

CORBA with C++ CORBA with C++ Last updated by Urs Rohrer on 10-Feb-2005