|
|
Contents
OverviewThis document gives an introduction to the C++ mapping of UNO. You should have read the A guide to language independent UNO, before reading with this document. It is a good idea to look at the relevant source code after reading this document. Some C++ components which follow the the concepts explained below can be found in the stoc, io or remotebridges modules, for example. TODO :
Shared library overview
In the above diagram the (C) means C-linkage, (C++) means C++ linkage. For all libraries you will need a C++ compiler to build. The base for all UDK-libraries is the sal-library, that contains all system abstractions and does not contain any UNO-specific data. The most commonly used C-functions can be accessed via C++ inline wrappers. This allows to call the functions from any other programming language. The salhelper-library offers additional base functionality, that could be implemented inline. The cppu ( = C Plus Plus Uno) library is the core uno library. It offers methods to access the UNO type library and allows to generically create, copy and compare values of UNO data types. Additionally all bridges (= mappings + environments) are administered here. msci_uno, sunpro5_uno and urp_uno are only examples for language binding libraries (MS VC++ 6, sunpro5 solaris). The cppuhelper library is a C++ library, that contains some important base classes for components (see below). C++ components are usually linked against cppuhelper. System abstraction layer (sal)The sal-library offers operating system dependent services behind one interface. The aim is to minimize, or eliminate, operating system dependent #ifdefs in libraries above sal. Further more basic features such as strings are implemented in sal. Sal exports only C-symbols, there are inline C++ wrappers for convenience where it is sensible. File accessosl::FileBaseosl::VolumeInfoosl::FileStatusosl::Fileosl::DirectoryItemosl::DirectoryThread safe refcountingosl_incrementInterlockedCount and osl_decrementInterlockedCount
allow to modify a thread safe 4 byte counter.
Threads and thread synchronization::osl::Mutex::osl::Condition::osl::Semaphore::osl::Thread(docu not yet available)
Interprocess communication::osl::Socket(docu not yet available)::osl::Pipe(docu not yet available)StringsThe string classes in sal (rtl::OUString
for Unicode-strings and
rtl::OString for byte strings) are C++ wrapper for refcounted
immutable C-strings.
The rtl::OUStringBuffer and
rtl::OStringBuffer allow efficient
concatenation of strings.
Byte sequenceThe::rtl::ByteSequence
is a C++ wrapper around
C-functions
for a refcounted piece of memory. The ByteSequence is binary compatible to
com::sun::star::uno::Sequence< sal_Int8>, both can be cast into each other.
C++ mapping of IDL-typesThe binary specification for the IDL to C++ mapping can be found here, where some typical use cases of the C++ mapping are shown. Interface referencesInterface references, seecom::sun::star::uno::Reference-template,
are used to hold interfaces. The reference constructor (ctor) acquires
(increases the refcount by one) the interface and the destructor releases the
interface.
Example 1 :
Example 2:
In the first line, an initial component context (factory context) is bootstrapped (see
below
, how this can be done).
The second line retrieves the bootstrapped service manager of the context.
The next line creates the service
com.sun.star.io.Pipe
and returns a reference
to XInterface (Note: the Weak referencesIn general every uno object allows to hold weak references on it (see OWeakObject). Weak references allow to retrieve a hard interface reference if the object has been not destroyed before. Example
SequenceFor every type in UNO exists another type, the sequence < type >. In C++,
this is managed by the Some basic examples how to use the template
AnyThe
ExceptionUNO exceptions can simply be thrown like C++ exceptions. Example :
The cppuhelper modulecppuhelper contains important base classes for UNO-objects, a bootstrap mechanism for the initial component context (factory context) and some other objects. The cppuhelper and salhelper libraries are the only C++-linkage libraries within the UDK. Weak objectThecppu::OWeakObject
is the suggested minimum base class that every uno object should support.
(see cppuhelper/weak.hxx). It implements a basic refcounting object and allows others to
hold the object weak (see weak references).
Example of an uno-object, that uses OWeakObject as base class.
The class implements an XOutputStream using stdc library. The constructor creates a file and stores the file handle in a class member. The task of queryInterface is to return the correct interface reference for the requested
type, therefore it must cast the acquire and release are delegated to OWeakObject to resolve ambiguities. The following three methods simply implement the XOutputStream interface. Note that error checking has been omitted to simplify the code (this is certainly a very poor XOutputSteam implementation). The methods have been implemented inline to shorten the source. There is certainly no advantage in inlining virtual methods and should not be done in general. The object is not scriptable because it does not support the XTypeProvider -interface. The Component helper
The implementation helperThe so called implementation helpers are an excellent template variation of the above base classes. The use can be best explained with a sample :
The implementation helper templates fulfill two tasks:
There are, nevertheless, situations where you can't use the implementation helper (for example if you must implement more than 10 interfaces or if you have to provide a more complex query interface). Weak aggregation objectDeriving from
The propertyset helperUse::cppu::OPropertySetHelper
as base class, if you want to implement XPropertySet interface. [...] to be continued.
There is no implementation helper variant for OPropertySetHelper.
The factory helperThe factory helpers allows to create factories for objects. See exported symbols for a use case for them.UNO contextsBootstrapping the initial component context (factory context)The initial startup of the UNO system requires some sophisticated bootstrapping to
get an initial component context (including a service manager) to proceed service
instantiation. The context provides you a service manager instance.
The function reads out all /SINGLETONS entries out of the registry and inserts
entries into the component context.
The typedescription manager singleton is raised to deliver types to the cppu core typelib, too.To handle registries in a flexible way, there are two helper functions to get a simple registry and nested registry implementation:
There is also another function to bootstrap the UNO system reading reading out of environment variables the way it is presented here.
The context holds arbitrary values which are recommended to be prefixed by the implementation name of the component that acknowledges a value, e.g. if you want to set the cache size of the stoc typedescription manager, set:
com.sun.star.comp.stoc.TypeDescriptionManager.CacheSize to n.
All API singletons are directly accessible by their name.When closing down the application, you have to manually dispose the component context, which disposes all singleton objects including the service manager. This has to be done, because the context holds a hard reference to its service manager as well as the service manager its default context (property "DefaultContext").
By default each new component context wrapping an existing one (delegating unknown
property requests to it) should add itself as event listener to dispose itself
when the previous one is disposed (that is chaining).
Alternatively, you can call the existing functions in servicefactory.hxx
to bootstrap a service manager instance.
But when closing down, it is mandatory to dispose the component context
(service manager's "DefaultContext" property).
Setting/ Retrieving the Current ContextThe current (task/ thread) context has to be manually set when launching a new thread. There is a pair of functions setting and getting the context inuno/current_context.h
and uno/current_context.hxx:
The first pair of functions is independent of the callers UNO environment while the second is defining inline functions for a C++ caller (more convenient). You should take care with what is handled in this thread/task-local container. C++ componentsC++ components are implemented in shared libraries (or modules in OpenOffice.org). The implementation of a sample component is documented here. Each module must support some C-symbols, which the shared-library-loader uses as entry points to access the components.Exported symbolsEach module must export 4 C functions to make the components available. TODO: List the header files required to export these symbols
Example (the implementation of the service is not shown here):
TODO: This is quite a lot of code. Let's roughly step through it. [...] Singletons / MultiInstance
Every component has to be implemented as multi-instance, i.e. upon loading the library
they can use the cppuhelper
Independent componentsA component is called independent if it is only linked against UDK libraries. The aim is to have an application that only uses independent components. The only external thing they need is a service manager to instantiate other components.Component registrationIn general, every application has a registry (in OpenOffice, it is called applicat.rdb ). The applicat.rdb contains the definition of all types used in the application and information how to instantiate a component. This information is written into the rdb by the component itself using the abovecomponent_writeInfo function.
The service There exists a command line tool for registration ( After the registration, the service is accessible directly through the servicemanager. Note that if you have created new UNO-types in IDL, the types must also be merged into the
applications registry (use the Common programming patterns
|



