Sun Java Solaris Communities My SDN Account

Article

CORBA for C++ Object Interoperability

 
 

April 2000

Summary

This article discusses the interoperability of Sun Forte C++ and Gnu g++ code via CORBA. CORBA bridge enables C++ objects to be compiled using different compilers to communicate in a distributed environment. It is a mechanism that creates, deploys, and manages objects, referred to as CORBA components, under a distributed environment. You can encapsulate application data and business logic within a component that can be used in a multi-tier environment. CORBA provides several other services, such as runtime management for objects, component location, and life cycle management. The article focuses on a simple procedure that allows C++ objects to interact in a "compiler independent" manner.

Introduction

Object orientated application development using C++ is severely constrained by compiler-imposed restrictions that essentially take away platform independence. This is mainly due to ABI and underlying name mangling grammar differences that are used by each compiler. Interoperability is possible only under compiler-imposed restrictions or exception range within the linkage specifications. However, in the case of using extern "C" linkage, it prevents mangling of C++ methods. CORBA, as defined by OMG, provides for interoperability, in addition to other features. The following sections illustrate the steps that are needed to facilitate communication and method invocation in a non-homogeneous C++ object environment.

CORBA Components

The CORBA architecture is ideal for defining, developing, and deploying flexible distributed systems. It allows you to encapsulate application data and business logic within a component that is used in a distributed environment. These objects are referred to as CORBA components. Hence a fundamental requirement for using CORBA platform is componentization of the business logic.

Interaction among components is referred to as component collaboration. In some cases, when you implement CORBA, you may encounter a rearchitecting effort, such as partitioning a complex application system into smaller components. For example, a simple client-server application fits into such framework. However, not all applications can be easily broken down into components. CORBA and ORB can be very useful tools to achieve interoperability among C++ objects.

g++ and c++ Components Communicate Using ORB

This study used 2 ORBs:

The first ORB is a public domain ORB (www.mico.org). It is available for download under gnu licensing model. You can download the entire source to build the ORB library. Mico does not implement all the CORBA specifications.

The second ORB is a commercial ORB that comes with wider functionality. ORBacus provides support for Sun's native compiler (WS 5.0), multithreading, and full compliance with CORBA specifications. It is an open architecture, and its complete source code is free for non-commercial use (http://www.ooc.com/ob).

For this article, the ORBs were built using both GNU and Sun workshop WS 5.0 C++ compilers, and only the naming service component was included during the build process. An important feature of CORBA is its use of IDL (interface definition language). IDL specifies interfaces between the CORBA components. For more details on IDL, you can refer to any book on CORBA. Finally, OA (Object Adapter) acts as an intermediary between a component implementation and ORB. ORB, through an OA, provides services, such as: generating and interpreting IOR (Interoperable Object Reference), registering objects, and invocating methods.

Back to Top


Hello Interface

The following example demonstrates the component interaction and interoperability. It shows a single client that invokes a component remotely via a server code, which can easily extend to multiple components (by using different compilers).

The following code is a simple hello interface:

interface Hello
{
  void hello();
};
Once you define the interface, you can use the IDL compiler to generate the C++ files.

Implementing Hello Component

Now you have a component defined interface implemented in C++, you can compile the component by using either gnu (g++) or the native compiler (CC).

The following code is the Hello component implementation:

#ifdef HAVE_STD_IOSTREAM
using namespace std;
#endif

void
Hello_impl::hello()
{
  count <<"Hello World"<<endl;
}

Back to Top


Instantiating Server Code

In order for the component to receive requests, you need to write a server code to instantiate the Hello component. The server code informs the ORB when the initialization is done.

The following is a sample server code that instantiates the Hello component; it is ready to receive requests:

#ifdef HAVE_STD_IOSTREAM
using namespace std;
#endif

int
main(int argc, char* argv[], char*[])
{
  try
    {
      //
      // Create ORB and BOA to generate the IOR reference files.
      //
      CORBA_ORB_var orb=CORBA_ORB_init(argc, argv);
      CORBA_BOA_var boa=orb->BOA_init(argc, argv);

      //
      // Create implementation object
      //
      Hello_var p=new Hello_impl; // Hello object instantiation

      //
      // Save reference. The object reference is stringified
      // and save to a file "Hello.ref"
      //
      CORBA_String_var s=orb->object_to_string(pP;
 

      const char* refFile="Hello.ref";
      ofstream out(refFile);
      if(out.fail())
      {
        cerr<<argv[0]<<":can't open `"<<refFile<<"`:"
          <<strerror(errno)<<endl;
        return 1;
      }

      out<<s<<endl;
      out.close();
      //
      // Run implemenation - Initialization is complete
      // and the server is ready to receive request.
      //
      boa->impl_is_ready(CORBA_ImplementationDef::_nil());
    }
    catch(CORBA_SystemException& ex)
    {
      OBPrintException(ex);
      return 1;
    }

    return 0;
  }

Compile the server code and the implementation by using the g++ compiler:

g++ server.cpp Hello_impl.cpp -lORBg++ -lsocket -lnsl

Back to Top


Invocating Remote Method

The following code shows a "client" code that invokes the method remotely on the instantiated object:

try
{
  //
  // Create ORB
  //
  CORBA_ORB_var orb=CORBA_ORB_init(argc, argv);

  //
  // Get "hello" object
  //
  const char* refFile="Hello.ref";
  ifstream in; // Must use open(name), not ifstream in(name) (VC++ bug)
  in.open(refFile);
  if(in.fail())
  {
    cerr<<argv[0]<<":can't open'"<<refFile<<"':"
      strerror(errno)<<endl;
    return 1;
  }

  char s[1000];
  in>>s;

  CORBA_Object_var obj=orb->string_to_object(s);
  assert(!CORBA_is_nil(obj));

  Hello_var hello=Hello::_narrow(obj);
  assert(!CORBA_is_nil(hello));

  //
  // Main loop
  //
  cout,,"Enter `h' for hello or `x' for exit:n";
  char c;
  do
  {
    count,,">";
    cin>>c;
    if(c=='h')
      hello->hello();
  }
  while(c!='x');
}
catch(CORBA_SystemException& ex)
{
  OBPrintException(ex);
  return 1;
}

return 0;

Stringified reference file interacts between the remote caller and the object. The CORBA method string_to_object() converts the stringified reference to object reference. Furthermore, the remote method is invoked on the object reference. The client side code and the associated files are compiled using the Sun's native WorkShop 5.0 compiler:

CC Client.cpp -IORBCC -lsocket -lsnl

This example assumes that there is a shared file system on which the references are written and invoked by the server and client. Alternatively, you can also use the naming services provided by the ORB to execute the component objects in a truly remote manner, which this article does not address.

Exception Handling and Other Limitations

This approach is not suitable for all applications. In cases where there is rearchitecturing, not all algorithms can be broken down into components. Where permissible, this approach has several advantages. When you write smaller CORBA components, they reduce complexity and allow remote execution and easier debugging. Finally, since C++ interfaces support exceptions, the exceptions throw on the remote method invocation are marshalled and sent back to the client side. You then use ORB to unmarshal the exceptions and return it to the client. This way, the C++ handling mechanism is extended to CORBA. This is not possible when you use other mechanisms such as specifying extern "C" linkage that allows object mixing.

April 2000

Back to Top


Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Comments:
Your email address (no reply is possible without an address):
Sun Privacy Policy

Note: We are not able to respond to all submitted comments.

Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.