<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.openoffice.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Gvb</id>
	<title>Apache OpenOffice Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.openoffice.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Gvb"/>
	<link rel="alternate" type="text/html" href="https://wiki.openoffice.org/wiki/Special:Contributions/Gvb"/>
	<updated>2026-10-18T15:33:03Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.14</generator>
	<entry>
		<id>https://wiki.openoffice.org/w/index.php?title=Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno&amp;diff=100767</id>
		<title>Uno/Cpp/Tutorials/Introduction to Cpp Uno</title>
		<link rel="alternate" type="text/html" href="https://wiki.openoffice.org/w/index.php?title=Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno&amp;diff=100767"/>
		<updated>2008-12-02T03:59:07Z</updated>

		<summary type="html">&lt;p&gt;Gvb: /* Strings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Overview==&lt;br /&gt;
This 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.&lt;br /&gt;
&lt;br /&gt;
TODO :&lt;br /&gt;
* Documentation of the exported symbols in the Components section&lt;br /&gt;
&lt;br /&gt;
==Shared library overview==&lt;br /&gt;
[[Image:udk_baselibraries.gif|center]]&lt;br /&gt;
&lt;br /&gt;
In the above diagram the (C) means C-linkage, (C++) means C++ linkage. For all libraries you will need a C++ compiler to build.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
msci_uno, sunpro5_uno and urp_uno are only examples for language binding libraries (MS VC++ 6, sunpro5 solaris).&lt;br /&gt;
&lt;br /&gt;
The cppuhelper library is a C++ library, that contains some important base classes for components (see &lt;br /&gt;
[[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno#Bootstrapping_the_initial_component_context|below]]). C++ components are usually linked against cppuhelper.&lt;br /&gt;
&lt;br /&gt;
==System abstraction layer (sal)==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===[[SDKCppLanguage#Files|File access]]===&lt;br /&gt;
&amp;lt;code&amp;gt;osl::FileBase&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;osl::VolumeInfo&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;osl::FileStatus&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;osl::File&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;osl::DirectoryItem&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;osl::Directory&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[[SDKCppLanguage#Threads|Thread]] safe refcounting===&lt;br /&gt;
osl_incrementInterlockedCount and osl_decrementInterlockedCount allow to modify a thread safe 4 byte counter.&lt;br /&gt;
&lt;br /&gt;
===Threads and thread synchronization===&lt;br /&gt;
&amp;lt;code&amp;gt;::osl::Mutex&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;::osl::Condition&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;::osl::Semaphore&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;::osl::Thread(docu not yet available)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Interprocess communication===&lt;br /&gt;
&amp;lt;code&amp;gt;::osl::Socket(docu not yet available)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;::osl::Pipe(docu not yet available)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Strings===&lt;br /&gt;
The [[SDKCppLanguage#Strings|String]] classes in sal ( rtl::OUString for Unicode-strings and rtl::OString for byte strings) are C++ wrappers for refcounted immutable C-strings. The rtl::OUStringBuffer and rtl::OStringBuffer allow efficient concatenation of strings.&lt;br /&gt;
&lt;br /&gt;
===Byte [[SDKCppLanguage#Sequences|sequence]]===&lt;br /&gt;
The ::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&amp;lt; sal_Int8&amp;gt;, both can be cast into each other.&lt;br /&gt;
&lt;br /&gt;
==C++ mapping of IDL-types==&lt;br /&gt;
The binary specification for the IDL to C++ mapping can be found [http://udk.openoffice.org/cpp/man/spec/cpp_spec.html here], where some typical use cases of the C++ mapping are shown.&lt;br /&gt;
&lt;br /&gt;
===Interface references===&lt;br /&gt;
Interface references, see com::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.&lt;br /&gt;
&lt;br /&gt;
Example 1:&lt;br /&gt;
{{:Uno/Cpp/Snippet/Object_Lifecycle}}&lt;br /&gt;
&lt;br /&gt;
Example 2:&lt;br /&gt;
{{:Uno/Cpp/Snippet/Instantiate_a_Service}}&lt;br /&gt;
&lt;br /&gt;
===Weak references===&lt;br /&gt;
In 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 not been destroyed before.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
{{:Uno/Cpp/Snippet/Dereference_a_WeakReference}}&lt;br /&gt;
&lt;br /&gt;
===Sequence===&lt;br /&gt;
For every type in UNO exists another type, the [[SDKCppLanguage#Sequences|sequence]] &amp;lt; type &amp;gt;. In C++, this is managed by the Sequence template, which is a wrapper around a refcounted C-struct. The sequence follows a copy on modify strategy (if the refcount is larger than 1, the sequence is copy-constructed). The sequence can only be used with UNO-types, because it needs a getCppuType for the element type ( which are generated by the build environment).&lt;br /&gt;
&lt;br /&gt;
Some basic examples how to use the template&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    // create an integer sequence with 3 elements,&lt;br /&gt;
    // elements are defaulted to zero.&lt;br /&gt;
        Sequence&amp;lt; sal_Int32 &amp;gt; seqInt( 3 );&lt;br /&gt;
&lt;br /&gt;
    // get a read write pointer (this method checks for&lt;br /&gt;
    // the refcount and does a copy on demand).&lt;br /&gt;
    // however, if you know, that the refcount is one&lt;br /&gt;
    // ( as in this case, the sequence has just been&lt;br /&gt;
    // constructed), you could avoid the check&lt;br /&gt;
    // (which is a C-call overhead)&lt;br /&gt;
    // by writing sal_Int32 *pArray =&lt;br /&gt;
    //                 (sal_Int32*) seqInt.getConstArray();&lt;br /&gt;
	sal_Int32 *pArray = seqInt.getArray();&lt;br /&gt;
&lt;br /&gt;
	// modify the members&lt;br /&gt;
	pArray[0] = 4;&lt;br /&gt;
	pArray[1] = 5;&lt;br /&gt;
	pArray[2] = 3;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
    sal_Int32 sourceArray[3] = {3,5,3};&lt;br /&gt;
&lt;br /&gt;
    // result is the same as above, but initialises from a buffer.&lt;br /&gt;
    Sequence&amp;lt; sal_Int32 &amp;gt; seqInt( sourceArray , 3 );&lt;br /&gt;
}&lt;br /&gt;
	&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    // construct a sequence of Property structs,&lt;br /&gt;
    // the structs are default constructed&lt;br /&gt;
    Sequence&amp;lt; Property &amp;gt; seqProperty(2);&lt;br /&gt;
	seqProperty.getArray()[0].Name = OUString::createFromAscii( &amp;quot;A&amp;quot; );&lt;br /&gt;
	seqProperty.getArray()[0].Handle = 0;&lt;br /&gt;
	seqProperty.getArray()[1].Name = OUString::createFromAscii( &amp;quot;B&amp;quot; );&lt;br /&gt;
	seqProperty.getArray()[1].Handle = 1;&lt;br /&gt;
&lt;br /&gt;
	// copy construct the sequence (The refcount is raised)&lt;br /&gt;
	Sequence&amp;lt; Property &amp;gt; seqProperty2 = seqProperty;&lt;br /&gt;
	&lt;br /&gt;
	// access a sequence&lt;br /&gt;
	for( sal_Int32 i = 0 ; i &amp;lt; seqProperty.getLength() ; i ++ )&lt;br /&gt;
	{&lt;br /&gt;
	    // Please NOTE : seqProperty.getArray() would also work, but  &lt;br /&gt;
	    //               it is very expensive, because a&lt;br /&gt;
	    //               unnecessary copy construction&lt;br /&gt;
	    //               of the sequence takes place.&lt;br /&gt;
	    printf( &amp;quot;%d\n&amp;quot; , seqProperty.getConstArray()[i] );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Any===&lt;br /&gt;
The [[SDKCppLanguage#Any|Any]] is a generic container, that stores a type and a value. Here are some basic examples, how to you use the Any :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
   sal_Int32 i = 5;&lt;br /&gt;
   OUString string = OUString::createFromAscii( &amp;quot;demo&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
   Any aInt,aString;&lt;br /&gt;
&lt;br /&gt;
   // put an sal_Int32 into an any&lt;br /&gt;
   aInt &amp;lt;&amp;lt;= i;&lt;br /&gt;
&lt;br /&gt;
   // put a string into an any&lt;br /&gt;
   aString &amp;lt;&amp;lt;= string;&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
   // extract an int out of an any&lt;br /&gt;
   sal_Int32 i2;&lt;br /&gt;
   if( aInt &amp;gt;&amp;gt;= i2 )&lt;br /&gt;
   {&lt;br /&gt;
       printf( &amp;quot;int successfully extracted %d!\n&amp;quot;  , i2 );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   // the any does no conversion from string to int during extraction,&lt;br /&gt;
   // use the typeconverter service for theses purposes.&lt;br /&gt;
   if( !( aString &amp;gt;&amp;gt;= i2 ) )&lt;br /&gt;
   {&lt;br /&gt;
       printf( &amp;quot;string could not be converted to an int\n&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Exception===&lt;br /&gt;
UNO exceptions can simply be thrown like C++ exceptions. Example :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void ArbitraryService::doSomething( const Any &amp;amp;a )&lt;br /&gt;
                             throws( IllegalArgumentException )&lt;br /&gt;
{   &lt;br /&gt;
   sal_Int32 i;&lt;br /&gt;
   if( ! (a &amp;gt;&amp;gt;= i ) )&lt;br /&gt;
   {&lt;br /&gt;
      // a int was specified to be in the any&lt;br /&gt;
      IllegalArgumentException exception;&lt;br /&gt;
      exception.Message = OUString::createFromAscii(&lt;br /&gt;
                                      &amp;quot;unexpected type in any&amp;quot; );&lt;br /&gt;
      exception.ArgumentPosition = 0;&lt;br /&gt;
      throw exception;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The cppuhelper module==&lt;br /&gt;
cppuhelper 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.&lt;br /&gt;
&lt;br /&gt;
===Weak object===&lt;br /&gt;
The cppu::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).&lt;br /&gt;
&lt;br /&gt;
Example of an uno-object, that uses OWeakObject as base class.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class OFileWriter : public OWeakObject, public XOutputStream&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    OFileWriter( char *pcFile ) : m_f( fopen( pcFile , &amp;quot;w&amp;quot; ) )&lt;br /&gt;
          {}&lt;br /&gt;
public:  // XInterface implementation&lt;br /&gt;
    virtual Any SAL_CALL queryInterface(&lt;br /&gt;
                const ::com::sun::star::uno::Type&amp;amp; aType ) throw()&lt;br /&gt;
    {   &lt;br /&gt;
	Any a = ::cppu::queryInterface(&lt;br /&gt;
	             aType, static_cast&amp;lt; XOutputStream * &amp;gt;( this ) );&lt;br /&gt;
&lt;br /&gt;
	if( a.hasValue() )&lt;br /&gt;
	{&lt;br /&gt;
	    return a;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	return OWeakObject::queryInterface( aType );&lt;br /&gt;
    }&lt;br /&gt;
    virtual void SAL_CALL acquire()&lt;br /&gt;
     	{ OWeakObject::acquire(); }&lt;br /&gt;
    virtual void SAL_CALL release()&lt;br /&gt;
    	{ OWeakObject::release(); }&lt;br /&gt;
&lt;br /&gt;
public: // XOutputStream implementation&lt;br /&gt;
    virtual void SAL_CALL writeBytes(&lt;br /&gt;
                const Sequence&amp;lt; sal_Int8 &amp;gt;&amp;amp; aData) throw  ()&lt;br /&gt;
    {&lt;br /&gt;
	fwrite( aData.getConstArray() , 1 , aData.getLength() , m_f );&lt;br /&gt;
    }&lt;br /&gt;
    virtual void SAL_CALL flush(void) throw  ()&lt;br /&gt;
    {&lt;br /&gt;
	fflush( m_f );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    virtual void SAL_CALL closeOutput(void) throw ()&lt;br /&gt;
    {&lt;br /&gt;
        fclose( m_f );&lt;br /&gt;
    }&lt;br /&gt;
private:&lt;br /&gt;
    FILE *m_f;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The class implements an XOutputStream using stdc library. The constructor creates a file and stores the file handle in a class member.&lt;br /&gt;
&lt;br /&gt;
The task of queryInterface is to return the correct interface reference for the requested type, therefore it must cast the this-pointer to the correct interface pointer. The task is simplified by the global queryInterface-template-method, which compares the requested type with the cast this-pointers. If they match, an any with the correct reference is returned, otherwise an empty (void) any is returned. If the latter case is true, the call is delegated to OWeakObject&amp;#039;s queryInterface.&lt;br /&gt;
&lt;br /&gt;
acquire and release are delegated to OWeakObject to resolve ambiguities.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
The object is not scriptable because it does not support the XTypeProvider -interface.&lt;br /&gt;
&lt;br /&gt;
===The Component helper===&lt;br /&gt;
cppu::OComponentHelper is the suggested base class for UNO-objects that must support the XComponent interface. The implementation(see cppuhelper/weak.hxx ) takes care of event listener administration and ensures correctly notifying all listeners in both possible cases (refcount drops to zero or dispose is called). OComponentHelper is derived from OWeakObject.&lt;br /&gt;
&lt;br /&gt;
===The implementation helper===&lt;br /&gt;
The so called implementation helpers are an excellent template variation of the above base classes. The use can be best explained with a sample :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class OFileWriter : public WeakImplHelper1&amp;lt; XOutputStream &amp;gt;&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    OFileWriter( char *pcFile ) : m_f( fopen( pcFile , &amp;quot;w&amp;quot; ) )&lt;br /&gt;
          {}&lt;br /&gt;
&lt;br /&gt;
public: // XOutputStream implementation&lt;br /&gt;
    virtual void SAL_CALL writeBytes(const Sequence&amp;lt; sal_Int8 &amp;gt;&amp;amp; aData) throw  ()&lt;br /&gt;
    {&lt;br /&gt;
	fwrite( aData.getConstArray() , 1 , aData.getLength() , m_f );&lt;br /&gt;
    }&lt;br /&gt;
    virtual void SAL_CALL flush() throw  ()&lt;br /&gt;
    {&lt;br /&gt;
	fflush( m_f );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    virtual void SAL_CALL closeOutput() throw  ()&lt;br /&gt;
    {&lt;br /&gt;
        fclose( m_f );&lt;br /&gt;
    }&lt;br /&gt;
private:&lt;br /&gt;
    FILE *m_f;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The implementation helper templates fulfill two tasks:&lt;br /&gt;
* correct queryInterface implementation (using the template parameter and their base classes as possible interfaces to query for).&lt;br /&gt;
* correct XTypeProvider implementation, so that the object is accessible by scripting languages. &lt;br /&gt;
&lt;br /&gt;
The helper exists in 4 variations&lt;br /&gt;
* WeakImplHelper : base class is OWeakObject&lt;br /&gt;
* WeakComponentImplHelper : base class is OWeakObject, implements the same stuff as OComponentHelper&lt;br /&gt;
* WeakAggImplHelper : base class is OWeakAggObject&lt;br /&gt;
* WeakAggComponentImplHelper : base class is OWeakAggObject, implements the same stuff as OComponentHelper &lt;br /&gt;
&lt;br /&gt;
Add the number of interfaces, you wish to implement, to the helper name ( something like va_arg for templates would be really cool). The implementation helper have the disadvantage, that the code is not debugable (because most of the code is implemented in macros), they have the advantage, that the error prone queryInterface and XTypeProvider implementation are not done by every application developer again and again (this saves really lots of debugging sessions). So using the implementation helper is the proposed way to implement UNO-objects.&lt;br /&gt;
&lt;br /&gt;
There are, nevertheless, situations where you can&amp;#039;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).&lt;br /&gt;
&lt;br /&gt;
===Weak aggregation object===&lt;br /&gt;
Deriving from cppu::OWeakAggObject makes your object able to be [http://udk.openoffice.org/common/man/concept/unointro.html#aggregation aggregated].&lt;br /&gt;
The propertyset helper&lt;br /&gt;
Use ::cppu::OPropertySetHelper as base class, if you want to implement XPropertySet interface. [...] to be continued. There is no implementation helper variant for OPropertySetHelper.&lt;br /&gt;
&lt;br /&gt;
===The factory helper===&lt;br /&gt;
The factory helpers allows to create factories for objects. See [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno#Exported_symbols| exported symbols]] for a use case for them.&lt;br /&gt;
&lt;br /&gt;
==UNO contexts==&lt;br /&gt;
===bootstrapping the initial component context (factory context)===&lt;br /&gt;
The initial startup of the UNO system requires some sophisticated [[UNO_registery_and_Bootstrapping#C.2B.2B_UNO_bootstrapping_via_defaultBootstrap_InitialComponentContext.28.29|Bootstrapping]]  to get an initial component context (including a service manager) to proceed service instantiation. The context provides you a service manager instance.&lt;br /&gt;
The cppuhelper function below can be called to bootstrap an initial component context with service manager upon a given registry. This includes insertion of initial the following service factories:&lt;br /&gt;
* (registry) service manager&lt;br /&gt;
* shared lib loader&lt;br /&gt;
* simple registry&lt;br /&gt;
* nested registry&lt;br /&gt;
* implementation registration&lt;br /&gt;
* registry typedescription provider&lt;br /&gt;
* typedescription manager&lt;br /&gt;
&lt;br /&gt;
;cppuhelper/bootstrap.hxx:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
Reference&amp;lt; XComponentContext &amp;gt; SAL_CALL bootstrap_InitialComponentContext(&lt;br /&gt;
    Reference&amp;lt; registry::XSimpleRegistry &amp;gt; const &amp;amp; xRegistry,&lt;br /&gt;
    OUString const &amp;amp; rBootstrapPath = OUString() )&lt;br /&gt;
    SAL_THROW( (Exception) );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
To handle registries in a flexible way, there are two helper functions to get a simple registry and nested registry implementation:&lt;br /&gt;
&lt;br /&gt;
;cppuhelper/bootstrap.hxx:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
Reference&amp;lt; registry::XSimpleRegistry &amp;gt; SAL_CALL createSimpleRegistry(&lt;br /&gt;
    const OUString &amp;amp; rBootstrapPath = OUString() )&lt;br /&gt;
    SAL_THROW( () );&lt;br /&gt;
&lt;br /&gt;
Reference&amp;lt; registry::XSimpleRegistry &amp;gt; SAL_CALL createNestedRegistry(&lt;br /&gt;
    const OUString &amp;amp; rBootstrapPath = OUString() )&lt;br /&gt;
    SAL_THROW( () );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is also another function to bootstrap the UNO system reading reading out of environment variables the way it is presented here.&lt;br /&gt;
&lt;br /&gt;
;cppuhelper/bootstrap.hxx:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
Reference&amp;lt; XComponentContext &amp;gt; SAL_CALL defaultBootstrap_InitialComponentContext()&lt;br /&gt;
    SAL_THROW( (Exception) );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
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 &amp;quot;DefaultContext&amp;quot;). 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).&lt;br /&gt;
&lt;br /&gt;
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&amp;#039;s &amp;quot;DefaultContext&amp;quot; property).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
    // get initial context&lt;br /&gt;
    Reference&amp;lt; XComponentContext &amp;gt; xContext( defaultBootstrap_InitialComponentContext() );&lt;br /&gt;
    OSL_ASSERT( xContext.is() );&lt;br /&gt;
    &lt;br /&gt;
    // retrieve typedescription manager singleton&lt;br /&gt;
    Reference&amp;lt; XHierarchicalNameAccess &amp;gt; xTDMgr;&lt;br /&gt;
    OSL_VERIFY( xContext-&amp;gt;getValueByName( OUString( RTL_CONSTASCII_USTRINGPARAM(&lt;br /&gt;
        &amp;quot;com.sun.star.reflection.TypeDescriptionManager&amp;quot;) ) ) &amp;gt;&amp;gt;= xTDMgr );&lt;br /&gt;
	&lt;br /&gt;
    // easier: retrieve service manager singleton&lt;br /&gt;
    Reference&amp;lt; XMultiComponentFactory &amp;gt; xSMgr( xContext-&amp;gt;getServiceManager() );&lt;br /&gt;
    /* same as:&lt;br /&gt;
    Reference&amp;lt; XMultiComponentFactory &amp;gt; xSMgr;&lt;br /&gt;
    OSL_VERIFY( xContext-&amp;gt;getValueByName( OUString( RTL_CONSTASCII_USTRINGPARAM(&lt;br /&gt;
        &amp;quot;com.sun.star.lang.ServiceManager&amp;quot;) ) ) &amp;gt;&amp;gt;= xSMgr );&lt;br /&gt;
    */&lt;br /&gt;
    &lt;br /&gt;
    // launch new typedescription manager instance with modified cache size,&lt;br /&gt;
    // NOTICE: knowing the context cache size key is implementation detail&lt;br /&gt;
    // of the raised component.  Caching is no concept of the implementation&lt;br /&gt;
    // and can thus be ignored by the implementation!&lt;br /&gt;
    &lt;br /&gt;
    // look at cppuhelper/component_context.hxx:&lt;br /&gt;
    Contextentry_Init aEntry;&lt;br /&gt;
    aEntry.bLateInitService = false;&lt;br /&gt;
    aEntry.name = OUString( RTL_CONSTASCII_USTRINGPARAM(&lt;br /&gt;
        &amp;quot;com.sun.star.comp.stoc.TypeDescriptionManager.CacheSize&amp;quot;) );&lt;br /&gt;
    aEntry.value = makeAny( (sal_Int32)0xdb0 );&lt;br /&gt;
    // create new context overriding cache size, rest is delegated to previous context&lt;br /&gt;
    Reference&amp;lt; XComponentContext &amp;gt; xNewContext( createComponentContext(&lt;br /&gt;
        &amp;amp;aEntry, 1, xContext );&lt;br /&gt;
    Reference&amp;lt; XInterface &amp;gt; xNewTDMgr( xSMgr-&amp;gt;createInstanceWithContext(&lt;br /&gt;
        OUString( RTL_CONSTASCII_USTRINGPARAM(&lt;br /&gt;
            &amp;quot;com.sun.star.reflection.TypeDescriptionManager&amp;quot;) ), xNewContext ) );&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
    Reference&amp;lt; XComponent &amp;gt; xComp( xContext, UNO_QUERY );&lt;br /&gt;
    OSL_ASSERT( xComp.is() );&lt;br /&gt;
    xComp-&amp;gt;dispose();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting/ Retrieving the Current Context===&lt;br /&gt;
The [http://udk.openoffice.org/common/man/concept/uno_contexts.html#current_context 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 in uno/current_context.h and uno/current_context.hxx:&lt;br /&gt;
&lt;br /&gt;
;uno/current_context.h:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
sal_Bool SAL_CALL uno_getCurrentContext(&lt;br /&gt;
    void ** ppCurrentContext,&lt;br /&gt;
    rtl_uString * pEnvTypeName, void * pEnvContext )&lt;br /&gt;
    SAL_THROW_EXTERN_C();&lt;br /&gt;
&lt;br /&gt;
sal_Bool SAL_CALL uno_setCurrentContext(&lt;br /&gt;
    void * pCurrentContext,&lt;br /&gt;
    rtl_uString * pEnvTypeName, void * pEnvContext )&lt;br /&gt;
    SAL_THROW_EXTERN_C();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;uno/current_context.hxx:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
namespace com { namespace sun { namespace star { namespace uno {&lt;br /&gt;
&lt;br /&gt;
inline Reference&amp;lt; XCurrentContext &amp;gt; SAL_CALL getCurrentContext()&lt;br /&gt;
    SAL_THROW( () );&lt;br /&gt;
inline bool SAL_CALL setCurrentContext( Reference&amp;lt; XCurrentContext &amp;gt; const &amp;amp; xContext )&lt;br /&gt;
    SAL_THROW( () );&lt;br /&gt;
&lt;br /&gt;
} } } }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;IDL interface:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;idl&amp;quot;&amp;gt;&lt;br /&gt;
module com { module sun { module star { module uno {&lt;br /&gt;
&lt;br /&gt;
interface XCurrentContext : com::sun::star::uno::XInterface&lt;br /&gt;
{ &lt;br /&gt;
    any getValueByName( [in] string Name );&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
}; }; }; };&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
==C++ components==&lt;br /&gt;
C++ [[Constructing_Components|components]] are implemented in shared libraries (or modules in OpenOffice.org). The implementation of a sample component is documented [[Uno/Cpp/Tutorials/component_tutorial| here]]. Each module must support some C-symbols, which the shared-library-loader uses as entry points to access the components.&lt;br /&gt;
&lt;br /&gt;
===Exported symbols===&lt;br /&gt;
Each module must export 4 C functions to make the components available.&lt;br /&gt;
&lt;br /&gt;
TODO: List the header files required to export these symbols&lt;br /&gt;
&lt;br /&gt;
# component_getImplementationEnvironmentFunc &lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
/**************************************************************&lt;br /&gt;
 * Function to determine the environment of the implementation.&lt;br /&gt;
 * If the environment is NOT session specific&lt;br /&gt;
 * (needs no additional context), then this function&lt;br /&gt;
 * should return the environment type name and leave ppEnv (0).&lt;br /&gt;
 *&lt;br /&gt;
 * @param  ppEnvTypeName environment type name;&lt;br /&gt;
 *                       string must be constant&lt;br /&gt;
 * @param  ppEnv	 function returns its environment&lt;br /&gt;
 *                       if the environment is session specific,&lt;br /&gt;
 *                       i.e. has special context&lt;br /&gt;
 */&lt;br /&gt;
typedef void (SAL_CALL * component_getImplementationEnvironmentFunc)(&lt;br /&gt;
    const sal_Char ** ppEnvTypeName,uno_Environment ** ppEnv);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The loader uses this function to determine the native environment of the component. In general, the component simply returns the compiler environment name. This enables us to use modules compiled by different compilers in the same process, assuming that a C++ to UNO bridge exists for each compiler.&lt;br /&gt;
# component_getDescriptionFunc&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
/************************************************************&lt;br /&gt;
 * Optional function to retrieve a component description.&lt;br /&gt;
 *&lt;br /&gt;
 * @return an XML formatted string containing a short&lt;br /&gt;
 *         component description&lt;br /&gt;
 */&lt;br /&gt;
typedef const sal_Char * (SAL_CALL * component_getDescriptionFunc)(void);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
The function must return a string that contains the XML-description of the component. This allows generic tools (testtools, implementation repository browsers, etc.) to collect information about the module.&lt;br /&gt;
# component_writeInfoFunc&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
/**********************************************************&lt;br /&gt;
 * Writes component registry info, at least writing the&lt;br /&gt;
 * supported service names.&lt;br /&gt;
 *&lt;br /&gt;
 * @param		pServiceManager	a service manager&lt;br /&gt;
 *			(the type is XMultiServiceFactory&lt;br /&gt;
 *                      to be used by the environment&lt;br /&gt;
 *                      returned by&lt;br /&gt;
 *                      component_getImplementationEnvironment)&lt;br /&gt;
 * @param		pRegistryKey	a registry key&lt;br /&gt;
 *			(the type is XRegistryKey to be used&lt;br /&gt;
 *                      by the environment returned by&lt;br /&gt;
 *                      component_getImplementationEnvironment)&lt;br /&gt;
 * @return		true if everything went fine&lt;br /&gt;
*/&lt;br /&gt;
typedef sal_Bool (SAL_CALL * component_writeInfoFunc)(&lt;br /&gt;
    void * pServiceManager, void * pRegistryKey );&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
This function is called by the service com.sun.star.registry.ImplementationRegistration. It passes an XMultiServiceFactory and an XRegistryKey interface pointer, which are already mapped into the modules environment. The function can now register all implementations and services into this registry key.&lt;br /&gt;
# component_getFactoryFunc&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
/*********************************************************&lt;br /&gt;
 * Retrieves a factory to create component instances.&lt;br /&gt;
 *&lt;br /&gt;
 * @param pImplName	desired implementation name&lt;br /&gt;
 * @param pServiceManager a service manager&lt;br /&gt;
 *			(the type is XMultiServiceFactory&lt;br /&gt;
 *                      to be used by the environment&lt;br /&gt;
 *                      returned by&lt;br /&gt;
 *                      component_getImplementationEnvironment)&lt;br /&gt;
 * @param pRegistryKey	a registry key&lt;br /&gt;
 *			(the type is XRegistryKey to be used&lt;br /&gt;
 *                      by the environment returned by&lt;br /&gt;
 *                      component_getImplementationEnvironment)&lt;br /&gt;
 * @return		acquired component factory&lt;br /&gt;
 *			(the type is XInterface to be used by the&lt;br /&gt;
 *                      environment returned by&lt;br /&gt;
 *                      component_getImplementationEnvironment)&lt;br /&gt;
*/&lt;br /&gt;
typedef void * (SAL_CALL * component_getFactoryFunc)(&lt;br /&gt;
    const sal_Char * pImplName,&lt;br /&gt;
    void * pServiceManager, void * pRegistryKey );&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
This function is usually called the first time a component needs to be instantiated. The function should return an acquired XInterface interface-pointer for the requested implementation name.&lt;br /&gt;
&lt;br /&gt;
Example (the implementation of the service is not shown here):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define IMPLEMENTATION_NAME &amp;quot;com.sun.star.comp.io.stm.Pipe&amp;quot;&lt;br /&gt;
const sal_Char SERVICE_NAME[] = &amp;quot;com.sun.star.io.Pipe&amp;quot;;&lt;br /&gt;
Sequence&amp;lt; OUString &amp;gt; pipe_getSupportedServiceNames()&lt;br /&gt;
{&lt;br /&gt;
   Sequence&amp;lt; OUString &amp;gt; seqNames(1);&lt;br /&gt;
   seqNames.getArray()[0] =&lt;br /&gt;
         OUString::createFromAscii( SERVICE_NAME );&lt;br /&gt;
   return seqNames;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Reference&amp;lt; XInterface &amp;gt; SAL_CALL pipe_CreateInstance(&lt;br /&gt;
   const Reference&amp;lt; XComponentContext &amp;gt; &amp;amp; xContext )&lt;br /&gt;
{&lt;br /&gt;
    return Reference &amp;lt; XInterface &amp;gt;(&lt;br /&gt;
              ( OWeakObject * ) new OPipe(xContext) );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
extern &amp;quot;C&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
void SAL_CALL component_getImplementationEnvironment(&lt;br /&gt;
	const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )&lt;br /&gt;
{&lt;br /&gt;
	*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;&lt;br /&gt;
}&lt;br /&gt;
//==================================================================&lt;br /&gt;
sal_Bool SAL_CALL component_writeInfo(&lt;br /&gt;
             void * pServiceManager, void * pRegistryKey )&lt;br /&gt;
{&lt;br /&gt;
   if (pRegistryKey)&lt;br /&gt;
   {&lt;br /&gt;
       Reference&amp;lt; XRegistryKey &amp;gt; xNewKey(&lt;br /&gt;
	   reinterpret_cast&amp;lt; XRegistryKey * &amp;gt;( pRegistryKey )-&amp;gt;createKey(&lt;br /&gt;
		OUString::createFromAscii(&lt;br /&gt;
		      &amp;quot;/&amp;quot; IMPLEMENTATION_NAME &amp;quot;/UNO/SERVICES&amp;quot; ) ) );&lt;br /&gt;
			&lt;br /&gt;
	const Sequence&amp;lt; OUString &amp;gt; &amp;amp; rSNL = pipe_getSupportedServiceNames();&lt;br /&gt;
	const OUString * pArray = rSNL.getConstArray();&lt;br /&gt;
	for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )&lt;br /&gt;
		xNewKey-&amp;gt;createKey( pArray[nPos] );&lt;br /&gt;
			&lt;br /&gt;
	return sal_True;&lt;br /&gt;
   }&lt;br /&gt;
   return sal_False;&lt;br /&gt;
}&lt;br /&gt;
//===================================================================&lt;br /&gt;
void * SAL_CALL component_getFactory(&lt;br /&gt;
	const sal_Char * pImplName,&lt;br /&gt;
	void * pServiceManager, void * pRegistryKey )&lt;br /&gt;
{&lt;br /&gt;
   void * pRet = 0;&lt;br /&gt;
&lt;br /&gt;
   if (pServiceManager &amp;amp;&amp;amp;&lt;br /&gt;
       rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)&lt;br /&gt;
   {&lt;br /&gt;
	Reference&amp;lt; XSingleComponentFactory &amp;gt; xFactory( createSingleComponentFactory(&lt;br /&gt;
	   reinterpret_cast&amp;lt; XMultiServiceFactory * &amp;gt;( pServiceManager ),&lt;br /&gt;
	   OUString::createFromAscii( IMPLEMENTATION_NAME ),&lt;br /&gt;
	   pipe_CreateInstance, pipe_getSupportedServiceNames() ) );&lt;br /&gt;
&lt;br /&gt;
	if (xFactory.is())&lt;br /&gt;
	{&lt;br /&gt;
	    xFactory-&amp;gt;acquire();&lt;br /&gt;
	    pRet = xFactory.get();&lt;br /&gt;
        }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return pRet;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
TODO: This is quite a lot of code. Let&amp;#039;s roughly step through it. [...]&lt;br /&gt;
&lt;br /&gt;
===Singletons / MultiInstance===&lt;br /&gt;
Every component has to be implemented as multi-instance, i.e. upon loading the library they can use the cppuhelper createSingleComponentFactory() as outlined above. The old functions createSingleFactory() etc. are deprecated and should be changed. One-instance components (using createOneInstanceFactory) are deprecated, too. The component implementation should not decide by itself whether it is one-instance. Instead of this, a component should explicitly retrieve shared objects (singletons) via its context. All singleton key name (context key names) are to specified in IDL, for example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;idl&amp;quot;&amp;gt;&lt;br /&gt;
module com { module sun { module star { module reflection {&lt;br /&gt;
&lt;br /&gt;
singleton TypeDescriptionManager&lt;br /&gt;
{&lt;br /&gt;
    service com::sun::star::reflection::TypeDescriptionManager;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
}; }; }; };&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Independent components===&lt;br /&gt;
A 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.&lt;br /&gt;
&lt;br /&gt;
===Component registration===&lt;br /&gt;
In 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 above component_writeInfo function.&lt;br /&gt;
&lt;br /&gt;
The service com.sun.star.registry.ImplementationRegistration can be used to register a shared library. The service exports the interface com.sun.star.registry.XImplementationRegistration, which offers the registerImplementation-method. The library name, the service name of the loader (in general com.sun.star.loader.SharedLibrary) and a reference to a XRegistryKey interface (where the data shall be written to) must all be passed to the method. If an empty reference is passed, the service uses the registry of the servicemanager.&lt;br /&gt;
&lt;br /&gt;
There exists a command line tool for registration (regcomp), that does this (just call the tool without parameters to see its usage).&lt;br /&gt;
&lt;br /&gt;
After the registration, the service is accessible directly through the servicemanager.&lt;br /&gt;
&lt;br /&gt;
Note that if you have created new UNO-types in IDL, the types must also be merged into the applications registry (use the regmerge tool for this purpose).&lt;br /&gt;
&lt;br /&gt;
==Common programming patterns==&lt;br /&gt;
* Threads and members&amp;lt;br&amp;gt;Access to members in unguarded sections are in general not thread safe. Thus the following code and may crash (where m_xFoo is a reference to an UNO object).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//NOT THREAD SAFE :&lt;br /&gt;
    MyComponent::do()&lt;br /&gt;
    {&lt;br /&gt;
        if( m_xFoo.is() )&lt;br /&gt;
            m_xFoo-&amp;gt;doSomething();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
//THREAD SAFE :&lt;br /&gt;
    MyComponent::do()&lt;br /&gt;
    {&lt;br /&gt;
        Reference &amp;lt; XFoo &amp;gt; xFoo;&lt;br /&gt;
      	{&lt;br /&gt;
      	    MutexGuard guard( m_mutex );&lt;br /&gt;
      	    xFoo = m_xFoo;&lt;br /&gt;
      	}&lt;br /&gt;
        if( xFoo.is() )&lt;br /&gt;
            xFoo-&amp;gt;doSomething();&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt; Between the check of m_xFoo.is() and the call m_xFoo-&amp;gt;doSomething(), the reference may be cleared by another thread or during the call of m_xFoo-&amp;gt;doSomething() may be cleared, which can lead to the destruction of the UNO-object.&amp;lt;br&amp;gt;The reference assignment is not thread safe, as it is not an atomic operation (the reference might be cleared by another thread, before the current thread reaches the osl_incrementInterlockedCount() function). Therefor each member access must be guarded.&amp;lt;br&amp;gt;Note that this holds also for other refcounted objects such as strings, sequences, etc.&amp;lt;br&amp;gt;This certainly implies performance overhead of locking a mutex. If you know, that a certain member can never be changed, it is correct not to guard access to this member. But keep in mind that your code should also be stable to small modifications. If you don&amp;#039;t need the performance in that piece of code, you should always choose the safer method. Code must be in first place correct and in second place fast.&lt;br /&gt;
&lt;br /&gt;
* Initialize static objects on demand&amp;lt;br&amp;gt;If there is need for a static object, do not initialize it before main. This is a serious performance hit at application startup. Use wrapper functions to access static data instead, so that they are initialized on demand.&lt;br /&gt;
&lt;br /&gt;
* Thread safe initializing static data - Initialization of non atomic static data, that is not initialized before main (see above) must be guarded. To make this efficient, do the following. &lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
Mutex * getInitMutex()&lt;br /&gt;
{&lt;br /&gt;
    static Mutex *pInitMutex = 0;&lt;br /&gt;
    if( ! pInitMutex )&lt;br /&gt;
    {&lt;br /&gt;
        ::osl::Guard guard( ::osl::Mutex::getGlobalMutex() );&lt;br /&gt;
        if( ! pInitMutex )&lt;br /&gt;
        {&lt;br /&gt;
            static ::osl::Mutex initMutex;&lt;br /&gt;
      	    pInitMutex = &amp;amp;initMutex;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return pInitMutex;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
MyStaticData *getMyStaticDataImpl()&lt;br /&gt;
{&lt;br /&gt;
    static MyStaticData staticData;&lt;br /&gt;
    return &amp;amp;staticData;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static g_pMyStaticData * =0;&lt;br /&gt;
inline MyStaticData *getMyStaticData()&lt;br /&gt;
{&lt;br /&gt;
    if( ! g_pMyStaticData )&lt;br /&gt;
    {&lt;br /&gt;
        ::osl::Guard guard( getInitMutex() );&lt;br /&gt;
        if( ! g_pMyStaticData )&lt;br /&gt;
        {&lt;br /&gt;
            g_pMyStaticData = getMyStaticDataImpl();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return g_pMyStaticData;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
This looks a bit more complicated than it really is, lets step through it. The aim is to retrieve a pointer to the static data (here MyStaticData) as fast as possible (the first access can be slower, because these are only one time costs), so getMyStaticData is inline. If the data has been initialized before, then access is very fast (in fact a check to zero overhead, no function call).&amp;lt;br&amp;gt;      The construction of the static data should not be an inline function, because the current version of gcc on the Mac has problems with static data in inline functions.&amp;lt;br&amp;gt;The mutex used to guard the initialization is also constructed in this example. The construction of the mutex is guarded by the ::osl::Mutex::getGlobalMutex(), one of the rare objects constructed before main. Why not use the global mutex directly for guarding ? The answer is that it can be done, if and ONLY if the constructor of MyStaticData does not call something you do not know. If the constructor does a UNO-call, which is bridged to another process, the reply for this call is dispatched in a different thread and this thread needs to initialize some static data of its own, then you have a deadlock (too many debugging sessions have been spent on this...!)&lt;br /&gt;
&lt;br /&gt;
* DON&amp;#039;T USE MACROS - There are a lot of different opinions on this topic, but I want to stress this topic here : Do not use macros if there are other solutions (inline functions, inline template functions, const vars, etc.). Using macros generally has the following drawbacks:&lt;br /&gt;
** It is not type safe. The compiler does fewer checks, which results in finding bugs at runtime instead of finding them at compile time.&lt;br /&gt;
** The debugger does not know the symbols (e.g. strings, constants).&lt;br /&gt;
** If code is executed within macros, it is not debuggable.&lt;br /&gt;
** The code gets very difficult to read. &lt;br /&gt;
&lt;br /&gt;
Code is read much more often read than it is written.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Using_Cpp_with_the_OOo_SDK|Using C++ with the OOoSDK]]&lt;br /&gt;
* [[OpenOffice_filters_using_the_XML_based_file_format|OpenOffice filters using the XML based file format]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Uno]]&lt;br /&gt;
[[Category:Uno:Cpp]]&lt;br /&gt;
[[Category:Tutorial]]&lt;br /&gt;
[[Category:Cpp]]&lt;/div&gt;</summary>
		<author><name>Gvb</name></author>
	</entry>
	<entry>
		<id>https://wiki.openoffice.org/w/index.php?title=Extensions_development_java&amp;diff=100766</id>
		<title>Extensions development java</title>
		<link rel="alternate" type="text/html" href="https://wiki.openoffice.org/w/index.php?title=Extensions_development_java&amp;diff=100766"/>
		<updated>2008-12-02T03:51:12Z</updated>

		<summary type="html">&lt;p&gt;Gvb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Extensions}}&lt;br /&gt;
&lt;br /&gt;
=== Java specific information for Extensions creation ===&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
* [[JavaEclipseTuto|Create UNO component in Java using Eclipse]]&lt;br /&gt;
To help you, there is an Eclipse plugin and a tutorial to use it. You can install the Eclipse plugin by using the updating site [http://cedric.bosdonnat.free.fr/ooeclipseintegration http://cedric.bosdonnat.free.fr/ooeclipseintegration].&lt;br /&gt;
&lt;br /&gt;
This article is one of the [[OpenOffice.org_Developer_Article_Contest|Article Contest]] winners. [[Extensions#Translating_these_pages|Any translation]] is welcomed.&lt;br /&gt;
&lt;br /&gt;
=== Tools ===&lt;br /&gt;
Tools which support the development of extensions:&lt;br /&gt;
* [[OpenOffice_NetBeans_Integration|OpenOffice NetBeans Integration]] provides wizards to create UNO components and client applications (based on the SDK and an office installation).&lt;br /&gt;
* The [http://development.openoffice.org/releases/2.0.4_sdk.html OpenOffice.org Software Development Kit](SDK) provides basic tools (like the idlc, javamaker) and some examples.&lt;br /&gt;
&lt;br /&gt;
[[Category:Extensions]]&lt;/div&gt;</summary>
		<author><name>Gvb</name></author>
	</entry>
	<entry>
		<id>https://wiki.openoffice.org/w/index.php?title=Extensions_development&amp;diff=100765</id>
		<title>Extensions development</title>
		<link rel="alternate" type="text/html" href="https://wiki.openoffice.org/w/index.php?title=Extensions_development&amp;diff=100765"/>
		<updated>2008-12-02T03:34:38Z</updated>

		<summary type="html">&lt;p&gt;Gvb: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Extensions}}&lt;br /&gt;
Developing extensions is an efficient way to bring value to OpenOffice.org without diving into core sources. Obviously all developers willing to [[Main_Page|develop at OpenOffice.org sources level]] are welcomed.&lt;br /&gt;
&lt;br /&gt;
OpenOffice.org enables third party tools creation through UNO bridges, allowing using many languages.&lt;br /&gt;
&lt;br /&gt;
The principle is to create UNO packages that can be listed in the OpenOffice.org [[Extensions_repository|Extensions repository]] and installed by end-users easily.&lt;br /&gt;
&lt;br /&gt;
This section gives newcomers as well as experienced developers some hints for developing Extensions in various languages and provides tools and frameworks to facilitate that development.&lt;br /&gt;
&lt;br /&gt;
Finally, popular Extensions may be integrated into OpenOffice.org, so it is important to follow common policies from beginning to ease this merging.&lt;br /&gt;
&lt;br /&gt;
==== Starting in a language ====&lt;br /&gt;
Addons can be written in various languages. Each section gives starting information to help you create your addon. Each section is dedicated to a language. It deals with specific points concerning the Extensions aspect. Resources regarding the OpenOffice.org API can be found on the [http://api.openoffice.org API project] and the UNO bridge language issues are at [http://udk.openoffice.org UDK project]. The [http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/OpenOffice.org_Developers_Guide OpenOffice.org Developer&amp;#039;s Guide] is a valuable source of information as well.&lt;br /&gt;
&lt;br /&gt;
The translations of these pages are welcomed and [[Extensions#Translating_these_pages|guidelines are available]].&lt;br /&gt;
&lt;br /&gt;
* [[Extensions_development_python|Starting in Python]]&lt;br /&gt;
* [[Extensions_development_basic|Starting in Basic]] and [[Documentation/BASIC_Guide|Documentation BASIC Guide]]&lt;br /&gt;
* [[Extensions_development_java|Starting in Java]]&lt;br /&gt;
*  [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno|Introduction to C++ and UNO]] and [[Using_Cpp_with_the_OOo_SDK|Using C++ with OOoSDK]]&lt;br /&gt;
* [[Extensions_development_vfp|Starting in Visual FoxPro (French)]]&lt;br /&gt;
* [[Non-code_extensions|Non programmatic Extensions]]&lt;br /&gt;
* [[Extensions_packaging|Extensions packaging]]&lt;br /&gt;
* [[Extensions_Integration_into_Installation_Set|Extensions Integration into Installation Set]]&lt;br /&gt;
* [[Spellchecker_Integration_into_Installation_Set|Adding Spellchecker Extensions into Installation Set]]&lt;br /&gt;
* [[Filter_extensions|Import and Export filter extensions using code or xslt]]&lt;br /&gt;
&lt;br /&gt;
==== Articles &amp;amp; Tutorials ====&lt;br /&gt;
&lt;br /&gt;
* [[Framework/Article/Generic_UNO_Interfaces_for_complex_toolbar_controls|Generic UNO Interfaces for complex toolbar controls]] &lt;br /&gt;
&lt;br /&gt;
* [[Framework/Article/Addon_Menu_Toolbar_Merging|Addon Menu Toolbar Merging]] &lt;br /&gt;
&lt;br /&gt;
* [[Framework/Tutorial/Popup_Menu_Controller|Popup Menu Controller]]&lt;br /&gt;
&lt;br /&gt;
* [[Framework/Tutorial/Statusbar_Controller|Statusbar Controller]]&lt;br /&gt;
&lt;br /&gt;
==== Books on OpenOffice.org Basic Programming ====&lt;br /&gt;
&lt;br /&gt;
* [http://www.amazon.com/OpenOffice-org-Macros-Explained-Andrew-Pitonyak/dp/1930919514/ OpenOffice.org Macros Explained] by Andrew Pitonyak&lt;br /&gt;
* [http://www.lulu.com/content/2905912 OpenOffice.org Basic Crash Course] by Dmitri Popov&lt;br /&gt;
* [http://www.amazon.com/Learn-OpenOffice-org-Spreadsheet-Macro-Programming/dp/1847190979/ Learn OpenOffice.org Spreadsheet Macro Programming] by Mark, Alexander Bain&lt;br /&gt;
* [http://www.amazon.de/Makros-OpenOffice-org-2-3-StarBasic-OpenOffice/dp/3836211114/ Makros in OpenOffice.org 2.3] von Thomas Krumbein (in German)&lt;br /&gt;
* [http://www.amazon.fr/Programmation-OpenOffice-org-Macros-OOoBasic-API/dp/2212117639/ Programmation OpenOffice.org 2] de Bernard Marcelly, Laurent Godard (in French)&lt;br /&gt;
&lt;br /&gt;
==== Tools &amp;amp; Frameworks ====&lt;br /&gt;
&lt;br /&gt;
* [http://codesnippets.services.openoffice.org Code snippets available in many languages]&lt;br /&gt;
* [[API/Samples|Code snippets in the Wiki]]&lt;br /&gt;
* [[Extensions_development_translation|Translation framework]]&lt;br /&gt;
* [[Extensions_Packager|Extensions Packager]] - BasicAddonBuilder - Extension Compiler&lt;br /&gt;
* Predefined wizards&lt;br /&gt;
* [[Extensions_introspection|Introspection Tools]]: discover the API&lt;br /&gt;
* [[OpenOffice_Eclipse_Integration|OpenOffice.org Eclipse Integration]] - OpenOffice.org development with Eclipse&lt;br /&gt;
* [[OpenOffice_NetBeans_Integration|OpenOffice.org NetBeans Integration]] - plug-in for NetBeans providing some nice features to simplify the development with and for OpenOffice.org (highlevel wizards, UNOIDL and xcu syntax highlighting, code completion, integrated API reference, ...)&lt;br /&gt;
* [[Extension_Development_with_IntelliJ_IDEA|Extension Development with IntelliJ IDEA]]: simple introduction how you can use the IntelliJ IDEA to develop OpenOffice.org extensions.&lt;br /&gt;
* [[OpenOffice_Maven2_Integration|OpenOffice.org Maven 2 integration]] - Maven plugin to build OpenOffice.org extensions.&lt;br /&gt;
&lt;br /&gt;
==== Best Practices ====&lt;br /&gt;
* [[Extensions_best_practices|How to write OO.o GUI Extensions today]]&lt;br /&gt;
&lt;br /&gt;
==== Project: Enhancing the Extensions Infrastructure of OpenOffice.org ====&lt;br /&gt;
* [[Extensions_improvements_proposal|Project Proposal (agreed by the Community June 2006)]]&lt;br /&gt;
* [[Extensions_improvements_plan_and_status|Project Status]]&lt;br /&gt;
&lt;br /&gt;
==== Improving the Extension Manager ====&lt;br /&gt;
* [[Extensions_feature_ideas|Feature ideas]]&lt;br /&gt;
[[Category:Extensions]]&lt;/div&gt;</summary>
		<author><name>Gvb</name></author>
	</entry>
</feed>