Writing the Implementation

We will write the implementation in the lib/ subdirectory of hello/. The first step is to run the Babel shell script to generate the library implementation code for the SIDL file. We will implement the library in C++. The simplified command to generate the Babel library code (assuming Babel is in your PATH) is 5.1:

% babel -sC++ -olib ../hello.sidl

In this Babel command, the ``-sC++'' flag, or its long form ``-server=C++'', indicates that we wish to generate C++ bindings for an implementation5.2. The ``-olib'' flag, or its long form ``-output-dir=lib'', defines the root directory of where the generated code should be placed.

This command will generate a large number of C and C++ header and source files. It is often surprising to newcomers just how much code is generated by Babel. Rest assured, each file has a purpose and there is a lot of important things being done as efficiently as possible under the hood.

Files are named after the fully-qualified class-name. For instance, a package Hello and class World would have a fully qualified name (in SIDL) as Hello.World. This corresponds to file names beginning with Hello_World5.3. For each class, there will be files with _IOR, _skel, _stub, or _impl appended after the fully qualified name. IOR files are always in ANSI C (source and headers), containing Babel's Intermediate Object Representation. Impl files contain the actual implementation, and can be in any language that Babel supports, in this case, they're C++ files. Impl files are the only files that a developer need look at or touch after generating code from the SIDL source. Skel files perform translations between the IORs and the Impls. In some cases (like Fortran) the Skels are split into a few files: some in C, some in the Impl language. In the case of C++, the Skels are pure C++ code wrapped in extern "C" {} declarations. If the file is neither an IOR, Skel, nor Impl, then it is likely a Stub. Stubs are the proxy classes of Babel, performing translations between the caller language and the IOR. Finally, the file babel.make is a Makefile fragment that will simplify writing the Makefile necessary to compile the library. You may ignore the babel.make file if you wish.

The only files that should be modified by the developer (that's you since you're implementing Hello World) are the ``Impls'', which are in this case files ending with _Impl.hh or _Impl.cc Babel generates these implementation files as a starting point for developers. These files will contain the implementation of the Hello library. Every implementation file contains many pairs of comment ``splicer'' lines such as the following:


std::string
Hello::World_impl::getMsg()
throw ()
{
    // DO-NOT-DELETE splicer.begin(Hello.World.getMsg)
    // Insert code here...
    // DO-NOT-DELETE splicer.end(Hello.World.getMsg)
}

Any modifications between these splicer lines will be saved after subsequent invocations of the Babel tool. Any changes outside the splicer lines will be lost. This splicer feature was developed to make it easy to do incremental development using Babel. By keeping your edits within the splicer blocks, you can add new methods to the hello.sidl file and rerun Babel without the loss of your previous method implementations. You shouldn't ever need to edit the file outside the splicer blocks.

For our hello application, the implementation is trivial. Add the following return statement between the splicer lines in the lib/Hello_World_Impl.cc file:


std::string
Hello::World_impl::getMsg()
throw ()
{
    // DO-NOT-DELETE splicer.begin(Hello.World.getMsg)
    return std::string("Hello World!");
    // DO-NOT-DELETE splicer.end(Hello.World.getMsg)
}

To keep the Makefile simple, we will use some GNU Make features. This Makefile may not work with other make implementations. The GNU gcc and g++ compilers are used in this example. The following Makefile in the lib/ subdirectory will compile the library files and create a shared library named libhello.so:


.cc.o:
    g++ -fPIC -I$(HOME)/babel/include -c $<
.c.o:
    gcc -fPIC -I$(HOME)/babel/include -c $< 

include babel.make
OBJS = ${IMPLSRCS:.cc=.o} ${IORSRCS:.c=.o} \
       ${SKELSRCS:.cc=.o} ${STUBSRCS:.cc=.o}

libhello.so: ${OBJS}
    g++ -shared -o $@ ${OBJS}

clean:
    ${RM} *.o libhello.so

You do not necessarily need to create a shared library for this example; you may generate a standard static library (e.g., libhello.a). However, in general, you must generate a shared library if you will be calling your library from Python or Java. To create the shared library archive libhello.so, simply execute make as follows:

% cd lib/
% make libhello.so



babel-0.10.2
users_guide Last Modified 2005-03-23

http://www.llnl.gov/CASC/components
components@llnl.gov