ChorusOS 5.0 Application Developer's Guide

Examples of Dynamic and Shared Applications

This section discusses two examples of dynamic and shared applications. In these examples, it is assumed that a standard development environment has been set up (system build tree, search path, boot and initialization of target machine).

In these examples, the chorus_root_directory is the path of the target root directory on the NFS host (for example /home/chorus/root), the name of the target is jericho, and the environment variable WORK refers to the directory used for building these examples.

Dynamic Link at Application Start-up

The following dynamic application uses a custom dynamic library which will be loaded and linked at application start-up. It uses the function foo() which is defined in the dynamic library. This function calls the bar() function defined in the main application.

The following is the dynamic application progdyn.c:

#include <chorus.h> 

extern void foo();

main() {
    foo();              /* calling foo defined in the library */
}

void bar() {
    printf ("bar called\n");
}

The following is the dynamic library libdyn.c:

#include <chorus.h> 

extern void bar();

void foo() {
    printf ("Calling bar\n");
    bar();              /* calling bar defined in the main application */
}
Building the Dynamic Library
  1. Create the directory and the Imakefile.

    Create a directory libdyndir in $WORK, containing libdyn.c and the following Imakefile:

    SRCS = libdyn.c
    DynamicLibraryTarget (libdyn.so, libdyn.o, , , ,)
    Depend(libdyn.c)
  2. Build the dynamic library.

    In the libdyndir directory, build the dynamic library libdyn.so using the commands ChorusOSMkMf, make depend, and make.

Building the Dynamic Application
  1. Create the directory and the Imakefile.

    Create a directory progdyndir in $WORK, containing progdyn.c and the following Imakefile:

    SRCS = progdyn.c
    DynamicUserTarget (progdyn, progdyn.o, , 
            $(WORK)/libdyndir/libdyn.so,
            $(WORK)/libdyndir/libdyn.so, )
    Depend(progdyn.c)
  2. Build the dynamic application.

    In the progdyndir directory, build the dynamic application progdyn using the commands ChorusOSMkMf, make depend and make.


    % ChorusOSMkMf $WORK
    % make depend
    % make
    
Running the Dynamic Application
  1. Copy the dynamic application.

    Copy the dynamic application into the /bin subdirectory of the chorus_root_directory directory:


    % cp $WORK/progdyndir/progdyn chorus_root_directory/bin 
    
  2. Copy the dynamic library.

    Copy the dynamic library into the /lib subdirectory of the chorus_root_directory directory:


    % cp $WORK/libdyndir/libdyn.so chorus_root_directory/lib 
    

    The following command will notify the runtime linker where to find the libdyn.so dynamic library:


    % rsh jericho setenv LD_LIBRARY_PATH /lib 
    

    Alternatively, set the runpath to /lib in the ldopts argument of the application macro (-rpath /lib).

  3. Start the application.

    Start the application and dynamically load the libdyn.so library, using the following command:


    % rsh jericho /bin/progdyn
    

Explicit Link of a Dynamic Library Using dlopen

The following program explicitly loads a dynamic library at runtime using the function dlopen(). This program searches for the address of the dynfunc() function (defined in the library) and calls this function.

The following is the dynamic program progdyn2.c:

#include <chorus.h>
#include <cx/dlfcn.h>

int main()
{
    void    (*funcptr)();       /* pointer to function to search */
    void    *handle;            /* handle to the dynamic library */

        /* finding the library */
    handle = dlopen ("libdyn2.so", RTLD_NOW);
    if !(handle) { printf ("Cannot find library libdyn2.so\n"); exit(1); } 

        /* finding the function in the library */
    funcptr = (void (*)()) dlsym (handle, "dynfunc");
    if !(funcptr) { printf ("Cannot find function dynfunc\n"); exit(1); }

        /* calling library function */
    (*funcptr)();
}

The following is the dynamic library libdyn2.c:

#include <chorus.h> 

void dynfunc() {
    printf ("Calling dynfunc\n");
}
Building the Program and the Library

The program and library discussed in the previous section are built in the same way as the previous example using two Imakefiles:

  1. Create the first directory.

    Create a directory called libdyn2dir in $WORK, containing libdyn2.c and the following Imakefile:

    SRCS = libdyn2.c
    DynamicLibraryTarget (libdyn2.so, libdyn2.o, , , , )
    Depend(libdyn2.c)
  2. Create the second directory.

    Create a directory progdyn2dir in $WORK, containing progdyn2.c and the following Imakefile:

    SRCS = progdyn2.c
    DynamicUserTarget (progdyn2, progdyn2.o, , , , )
    Depend(progdyn2.c)
Running the Dynamic Program
  1. Copy the program.

    Copy the dynamic program into the /bin subdirectory of the chorus_root_directory directory:


    % cp $WORK/progdyn2dir/progdyn2 chorus_root_directory/bin 
    
  2. Copy the library.

    Copy the dynamic library into the /lib subdirectory of the chorus_root_directory directory:


    % cp $WORK/libdyn2dir/libdyn2.so chorus_root_directory/lib 
    
  3. Notify the runtime linker.

    Use the following command to notify the runtime linker where to find the libdyn2.so dynamic library:


    % rsh jericho setenv LD_LIBRARY_PATH /lib
    
  4. Start the program.

    Use the following command to start the program:


    % rsh jericho arun /bin/progdyn2 
    

    At program start-up, the runtime linker will only load the progdyn2 executable . The libdyn2.so library is loaded when the dlopen() function is called.

Dynamic Link of a Shared Library at Application Start-up

A small modification to the previous example enables a shared application to load a shared library dynamically.

Loading a Shared Library Dynamically
  1. Create the shared library file.

    Copy the libdyn.c file into the libshareddir directory and rename it libshared.c. The ensuing Imakefile will build a PIC binary object file called libshared.o and a shared library named libshared.so as follows:

    FPIC = ON
    SRCS = libshared.c
    SharedLibraryTarget (libshared.so, libshared.o, , , , )
    Depend($(SRCS))

  2. Create the shared program file.

    Copy the progdyn.c file into the progshareddir directory and rename it progshared.c. The ensuing Imakefile will build a PIC binary object file called progshared.o and an executable file called progshared:

    FPIC = ON
    SRCS = progshared.c
    LIBPATH = <pathname of the shared library directory>
    SharedUserTarget (progshared_u, progshared.o,
       $(UTILS_LIB) $(CLX_UTILS_LIB), -L$(LIBPATH)
       -Xlinker -rpath -Xlinker/shared -lshared,,)
    Depend($(SRCS))

  3. Copy the shared application.

    Copy the shared application into the /bin subdirectory of the chorus_root_directory directory:


    % cp $WORK/progshareddir/progshared_u chorus_root_directory/bin 
    

  4. Copy the shared library.

    Copy the shared library into the /shared subdirectory of the chorus_root_directory directory:


    % cp $WORK/libshareddir/libshared.so chorus_root_directory/shared
    


    Note -

    There is no need to set LD_LIBRARY_PATH as the path for the runtime linker. This path was specified in the Imakefile by setting the -Xlinker -rpath option.


  5. Start the application.

    The following command starts the application and loads the libshared.so and libc.so libraries (if they have not already been loaded by another application):


    % rsh jericho /bin/progshared_u
    

Explicit Linking of a Shared Library Using dlopen

The following procedure enables a shared program to load a shared library explicitly.

Linking a Shared Library Using dlopen
  1. Create the library file.

    Copy the libdyn2.c file into the libshared2dir directory and rename it libshared2.c. The following Imakefile will build a shared library called libshared2.so:

    FPIC = ON
    SRCS = libshared2.c
    SharedLibraryTarget (libshared2.so, libshared2.o,,,,)
    Depend($(SRCS))

  2. Create the program file.

    Copy the progdyn2.c file into the progshared2dir directory and rename it progshared2.c. The following Imakefile will build a PIC binary object file called progshared2.o and an executable file called progshared2

    FPIC = ON
    SRCS = progshared2.c
    SharedUserTarget (progshared2_u, progshared2.o,
        $(UTILS_LIB) $(CLX_UTILS_LIB),,,)
    Depend($(SRCS))

  3. Copy the application.

    Copy the shared application into the /bin subdirectory of the chorus_root_directory directory:


    % cp $WORK/progshared2dir/progshared2_u chorus_root_directory/bin 
    

  4. Copy the shared library.

    Copy the shared library into the /lib subdirectory of the chorus_root_directory directory:


    % cp $WORK/libshared2dir/libshared2.so chorus_root_directory/lib 
    

  5. Notify the runtime linker.

    The following command will notify the runtime linker where to find the libshared2.so shared library:


    % rsh jericho setenv LD_LIBRARY_PATH /lib/shared:/lib 
    

    Alternatively, set the runpath to /lib in the ldopts argument of the program macro (-rpath /lib).

  6. Start the program.

    The following command will start the program and load the libshared2.so and libc.so libraries (if they have not already been loaded by another actor):


    % rsh jericho /bin/progshared2