Keywords: doc

Next: Making Objects Persistent Up: Activation Modes Previous: Activation Mode Per Method

### Activation Mode Library

All activation modes discussed up until now assume client and server are different programs that run in separate processes. This approach has the advantage that client and server can be bound to each other dynamically during runtime. The drawback is the overhead for doing method invocations across process boundaries using some kind of IPC. The activation mode library eliminates this drawback while still allowing runtime binding. This is achieved by loading an object implementation (called a module from now on) into the running client. Invoking methods on an object loaded this way is as fast as a C++ method invocation.

A client that wants to use this feature does not differ from other clients, only the loadable module requires special code and you have to create a special entry in the implementation repository. To give you an example we want to change the bank account example from section 3.3.3 to make use of dynamic loading. The only change in the client is the address specified in the call to `bind()`: we have to use `"local:"` instead of `"inet:localhost:8888"`, because we want to bind to the dynamically loaded object running in the same process:

     1: // file account_client2.cc
     2:
     3: #include "account.h"
     4:
     5:
     6: int main( int argc, char *argv[] )
     7: {
     8:   // ORB initialization
     9:   CORBA::ORB_var orb = CORBA::ORB_init( argc, argv, "mico-local-orb" );
    10:   CORBA::BOA_var boa = orb->BOA_init( argc, argv, "mico-local-boa" );
    11:
    12:   CORBA::Object_var obj
    13:     = orb->bind ("IDL:Account:1.0", "local:");
    14:   if (CORBA::is_nil (obj)) {
    15:      // no such object found ...
    16:   }
    17:   Account_var client = Account::_narrow( obj );
    18:
    19:   client->deposit( 700 );
    20:   client->withdraw( 250 );
    21:   cout << "Balance is " << client->balance() << endl;
    22:
    23:   return 0;
    24: }

Here is the code for the loadable module:

     0: // file module.cc
     1:
     2: #include "account.h"
     3: #include <mico/template_impl.h>
     4:
     5: class Account_impl : virtual public Account_skel
     6: {
     7:   // unchanged, see section "MICO Application"
     8:   // ...
     9: };
    10:
    11: static Account_ptr server = Account::_nil();
    12:
    13: extern "C" CORBA::Boolean
    14: mico_module_init (const char *version)
    15: {
    16:   if (strcmp (version, MICO_VERSION))
    17:     return FALSE;
    18:   server = new Account_impl;
    19:   return TRUE;
    20: }
    21:
    22: extern "C" void
    23: mico_module_exit ()
    24: {
    25:   CORBA::release (server);
    26: }

Lines 13-20 define a function `mico_module_init()` that is called when the module is loaded into the running client. Note that this function must be declared as `extern "C"` to avoid C++ name mangling. The `version` argument to `mico_module_init()` is a string specifying the MICO-version of the client the module is loaded into. Lines 16 and 17 check if this version is the same as the MICO-version the module was compiled with and make module initialization fail by returning `FALSE` if they differ. Otherwise a new account object is created and `TRUE` is returned indicating successful module initialization. Note that `mico_module_init()` must not perform ORB and BOA initialization since the client the module is loaded into did this already. The function `mico_module_exit()` is called just before the module is unloaded from the client and should release all allocated resources: in our example the account object created in `mico_module_init()`. `mico_module_exit()` is only called if `mico_module_init()` returned `TRUE`. Modules have to be compiled as a shared library, see section 4.6 for details and an example.

Although communication does not go through the BOA daemon when using loadable modules you need a running `micod` because you have to create an implementation repository entry for the module. See section 4.3.3 for details. The directory `demo/shlib` contains a complete example.

There is currently one problem with loadable modules: throwing exceptions from a loadable module into non-loadable module code results in a segmentation fault. This is not a bug in MICO but in the GNU-C++ compiler and/or dynamic loader.

Next: Making Objects Persistent Up: Activation Modes Previous: Activation Mode Per Method