Implementation Loader

From Apache OpenOffice Wiki
Jump to: navigation, search

When you are raising a service by name using the service, the service manager decides an implementation name, code location and an appropriate loader to raise the code. It is commonly reading out of a persistent registry storage, for example, services.rdb (until 1.1.0 applicat.rdb), for this purpose. Previously, the regcomp tool has registered components into that registry during the Apache OpenOffice setup. The tool uses a service called for this task.

A loader knows how to load a component from a shared library, a .jar or script file and is able to obtain the service object factory for an implementation and retrieve information being written to the registry. A specific loader defines how a component implementer has to package code so that it is recognized by UNO. For instance in C++, a component is a shared library and in Java it is a .jar file. In a yet to be developed loader, the implementer of the loader has to decide, what a component is in that particular language - it might as well be a single script file.

The interface looks like the following:

  interface XImplementationLoader: com::sun::star::uno::XInterface
   com::sun::star::uno::XInterface activate ( [in] string implementationName, 
         [in] string implementationLoaderUrl, 
         [in] string locationUrl, 
         [in] com::sun::star::registry::XRegistryKey xKey ) 
         raises( com::sun::star::loader::CannotActivateFactoryException ); 
   boolean writeRegistryInfo ( [in] com::sun::star::registry::XRegistryKey xKey, 
         [in] string implementationLoaderUrl, 
         [in] string locationUrl ) 
         raises( com::sun::star::registry::CannotRegisterImplementationException ); 

The locationUrl argument describes the location of the implementation file, for example, a jar file or a shared library. The implementationLoaderUrl argument is not used and is obsolete. The registry key xKey writes information about the implementations within a component into a persistent storage. Refer to Write Registration Info Using a Helper Method for additional information.

The method writeRegistryMethod() is called by the regcomp tool to register a component into a registry.

The activate() method returns a factory for a concrete implementation name.

Implmentation loaders

The loader is often implemented in C/C++. When the loader is instantiated, it is responsible for starting up the language runtime, for example, Java VM, Python interpreter, through implementation. After starting up the runtime, the loader starts up the UNO language binding as discussed in the previous chapter, and bridge the XRegistryKey interface and the initial factory interface.

Shared Library Loader

This section discusses the loader for local components written in C++ that are loaded by the service. Every type safe programming language that stores its code in shared libraries should implement the bridge with environments and mappings as discussed in chapters UNO Bridge and UNO C++ Bridges. These programming languages can reuse the existing loader without creating a new one.

When the shared library is mapped into the running process, for example, using osl _loadModule(), the shared library loader retrieves defined C symbols out of the library to determine the compiler that built the code. This function symbol is called component_getImplementationEnvironment(). When the code is compiled with the Microsoft Visual C++ compiler, it sets a pointer to a string called "msci", with gcc 3.0.1 a string "gcc3" which is a UNO environment type name. A UNO environment is connected with the code that runs in it, for example, the code compiled with gcc3 runs in the UNO environment with type name gcc3.

In addition to the environment type name, a UNO environment defines a context pointer. The context pointer and environment type name define a unique UNO environment. Although the context pointer is mostly null, it is required to identify the environments apart for the same type, for example, to identify different Java virtual machine environments when running a UNO object in two different Java virtual machines within the same process. Both environments have the same type name "java", but different context pointers. In local (C++) code, the context pointer is irrelevant, that is, set to null. The type name determines the UNO runtime environment.

When the loader knows the environment the code comes from, it decides if bridging is required. Bridging is needed if the loader code is compiled with a different compiler, thus running in a different environment. In this case, the loader raises a bridge to speak UNO with the component code.

The loader calls on two more functions related to the above XimplementationLoader interface. All of these symbols are C functions and have the following signatures:

  extern "C" void SAL_CALL component_getImplementationEnvironment(
        const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv );
  extern "C" sal_Bool SAL_CALL component_writeInfo(
        void * pServiceManager, void * pRegistryKey );
  extern "C" void SAL_CALL component_getFactory(
        const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey );

The latter two functions expect incoming C++-UNO interfaces, therefore the loader needs to bridge interfaces before calling the functions as stated above.


The loader uses the cppu core runtime to map an interface, specifying the UNO runtime environment that needs the interface mapping. The cppu core runtime raises and connects the appropriate bridges, and provides a unidirectional mapping that uses underlying bidirectional bridges. Under Unix, the name of the bridge library follows the naming convention lib<SourceEnvironment>_<TargetEnvironment>., Under Windows, <SourceEnvironment>_<TargetEnvironment>.dll is used. For instance, is the bridge library for mappings from gcc3 to binary UNO, and msci_uno.dll maps from MS Visual C++ to binary UNO. The bridges mentioned above all bridge to binary UNO. Binary UNO is only used as an intermediate environment. In general, do not program binary UNO in clients. The purpose is to reduce the number of necessary bridge implementations. New bridges have to map only to binary UNO instead of all conceivable bridge combinations.

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages