UNO registery and Bootstrapping

From Apache OpenOffice Wiki
Revision as of 13:24, 26 May 2006 by SergeMoutou (Talk | contribs)

Jump to: navigation, search

OpenOffice.org can be extended : you can add features in OooBasic, in C++, in Java, in Python ... These added features are called Add-Ons, components, Add-ins (discussed in chapter 13.1) and we can wonder how Openoffice.org knows something about the corresponding code ? The tools involved in this chapter are regview, regcomp, regmerge and idlc.

Why UNO registry ?

It is common for programmer to develop a program and link it with a static library. If the library is a dynamic one the linking problem is let to Operating System : this OS have to know if the library is already loaded and if not where it lies. Let us be more concrete with an example.

LibraryExample.png

In the example above in Figure above our program example.cxx calls something in mylib.so or mylib.dll (the arrow means an interaction). This is done in a very simple way if both are compiled with same language : under Linux we use a -Lmylib.so when compiling example.cxx (more here). Then when you launch example binary executable when it needs what is in mylib.so it asks OS to load it. The case is a little more complicated if mylib.so is compiled with an other language than C++ : you have to learn how to pass parameters in C++ to reach the content of mylib.so. This is feasible changing a little example.cxx code. But what happens if you have a binary executable program and you want to give him new features with a dynamic library ? This can be done with OpenOffice.org as already mentioned.

What kind of problems OpenOffice has then to carry out ? First of all, it is impossible for Openoffice.org to know in advance what is the name of the library (it's a name you choose). Then OpenOffice.org must provide a mechanism to know its name : this is one of the goals of registry. Is the name of the dynamic library enough ? No, if you imagine you can extend with two or more libraries : it is important to know that foo1 procedure/method comes from foo_lib1 library and foo2 from foo_lib2... In OpenOffice.org this is generalized saying such an interface comes from such a library ... There is a lot of other problems to resolve before making it working properly. For example a problem with the name of procedure/methods : if you write it in C or in C++ the exported names will differ. And the parameters, how do you pass them ? Imagine OOoCalc call something in mylib.so  : it is unimaginable to ask OOocalc users to write something describing how parameters are passed in their OOoCalc formula ! OpenOffice has to know how pass a parameter in your library. This is done with what is called implementation environment. This done with specifying that every dynamic library has to export :

[cpp] //Listing 1 How to get the Implementation Environnement in a dynamic library // C++ extern "C" void SAL_CALL component_getImplementationEnvironment(

                const sal_Char ** ppEnvTypeName, 
                uno_Environment ** ppEnv ) 

The passing parameters way is fixed by extern C. This is not a decoration but an obligation. If not present a ["component_getImplementationEnvironment" could not be found] error will be thrown when you try to registry (with regmerge for instance).

Registery uses rdb files in a binary file format. Binaries format are difficult to read by human and then a tool is provided to give the information in human readable form (see regview in further section 11.3).

An advise : at first you can skip the rest of this chapter particularly if you are not interested in components (chapter 13 is about them). But not only components use registry : the UNO/automation (chapter 4) use registry in a different way : we discuss this way in section 11.5.

How to use UNO registeries

Documentation for registries already exist at : uno registeries. More information at : ooomacros where these tools are available :

  • Add On Tool

Author: Bernard Marcelly

  • Add On Installer

Author: Didier Lachièze, with code from Danny Brewer, Bernard Marcelly and Andrew Brown

  • Basic Library Installer

Author: Danny Brewer, with code from Andrew Brown & Didier Lachièze

In my opinion, the simpler way to registery is to modify the file unorc (under linux) or uno.ini (under Windows). You have to put the file your_library.uno.rdb in <OOo>/program directory, and editing/modifying the file <OOo>/program/unorc (under linux) adding (last line your_library.uno.rdb) :

#unorc or uno.ini
[Bootstrap] 
UNO_SHARED_PACKAGES=${$SYSBINDIR/bootstraprc:BaseInstallation}/share/uno_packages 
UNO_SHARED_PACKAGES_CACHE=$UNO_SHARED_PACKAGES/cache 
UNO_USER_PACKAGES=${$SYSBINDIR/bootstraprc:UserInstallation}/user/uno_packages 
UNO_USER_PACKAGES_CACHE=$UNO_USER_PACKAGES/cache 
UNO_TYPES=$SYSBINDIR/types.rdb ?$UNO_SHARED_PACKAGES_CACHE/types.rdb ?$UNO_USER_PACKAGES_CACHE/types.rdb 
UNO_SERVICES= ?$UNO_USER_PACKAGES_CACHE/services.rdb ?$UNO_SHARED_PACKAGES_CACHE/services.rdb $SYSBINDIR/services.rdb ?$SYSBINDIR/your_library.uno.rdb

Don't forget to register the location of your_library.uno.so in the your_library.uno.rdb. This is done with regcomp tool :

regcomp -Register -r your_library.uno.rdb -c <somewhere>/your_library.uno.so

An other way is to use pkgchk or the recent unopkg for Ooo2.0x.

The Bootstrap

Bootstrapping can be defined in saying it's the way to obtain a service manager. We present two different examples of bootstraping.

C++ UNO bootstrapping via defaultBootstrap_InitialComponentContext()

We have have already described this bootstrap method because it concerns the classical SDK example we started with in chapter 4 (see <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding). We provide here two different views to explain how it works. First we recall with the Figure below how we program it. It's easy to see the first C++ instruction is [cpp] //C++ defaultBootstrap_InitialComponentContext(); But when drawing details from the figure we cannot infer how it works and particularly with registery. It's only because Figure below is a C++/Java programmer point of view.

Ch4Fig1bootstrap.png

To see what happens during the beginning of bootstrap, we go and see the binary in <OpenOffice.org1.1_SDK>/LINUXexample.out/bin where binaries are constructed by default makefiles. We see three files :

  • office_connect the binary executable
  • office_connectrc : file with this content :
UNO_TYPES=$SYSBINDIR/office_connect.rdb
UNO_SERVICES=$SYSBINDIR/office_connect.rdb
  • office_connect.rdb

The files construction will perhaps help us to understand beter. We give again the make dependency of office_connect in Figure 1.4 which shows us how office_connect.rdb is constructed :

  • a regmerge starting from types.rdb
  • a regcomp to register somes classics uno.so files.

And now to learn how office_connect.rdb is used we have to search in makefile how the binary is launched : the line

%.run: $(OUT_BIN)/%$(EXE_EXT)
	cd $(subst /,$(PS),$(OUT_BIN)) && $(basename $@)

is expanded as

cd ../../../../LINUXexample.out/bin && office_connect

which shows no reference to office_connect.rdb. Then we have to probe how it works.

  • the office_connectrc is automaticly loaded. One way to test that is to rename this file which gives as result
make: *** [office_connect.run] Erreur 134
  • renaming only office_connect.rdb gives the same error :
make: *** [office_connect.run] Erreur 134
  • renaming office_connect.rdb as office_connect2.rdb and changing office_connectrc content, as seen below, works well.
UNO_TYPES=$SYSBINDIR/office_connect2.rdb
UNO_SERVICES=$SYSBINDIR/office_connect2.rdb

Conclusion : we have found how it works : when you launch a binary it automaticaly load office_connectrc and put the file office_connect2.rdb in the good place.

C++ UNO bootstrapping via Bootstrap_InitialComponentContext()

The documentLoader example (see <OpenOffice.org1.1_SDK>/examples/cpp/DocumentLoader) uses an other way to bootstrap. We want to describe it now. As usualy we first begin with program framework in the Figure below.

SecondBootstrap.png

In this second case we clearly see that DocumentLoader.rdb file is involved and loaded. The only difference is with registry. We find again a rdb file but not a rc file. The consequence is the presence of a regcomp command specific to regitery the binary/executable file.

This example will not work if OpenOffice.org is not running. In this example, the interaction between OpenOffice.org and some.bin is through the network. In other words, the programs can run on different computers. You must run OpenOffice.org in such a way it waits for an UNO connection (here only from localhost) :

<Ooo>/program/soffice "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"

Playing with regview

To do

How can we registry in C++ ?

It is easy to find an example with registry. As first example we can take the counter example.

Personal tools