Difference between revisions of "Counter Example"

From Apache OpenOffice Wiki
Jump to: navigation, search
Line 1: Line 1:
This example given with the SDK contains two files : counter.cxx and countermain.cxx. These files shows differencies with Listing 3 and Listing 4 previously tackled because they have to run with OpenOffice.org now. This little example uses a registered external module (counter.uno.so build from counter.cxx) and a main program (countermain.cxx) which uses it.  
+
This example given with the SDK contains two files : counter.cxx and countermain.cxx. These files shows differencies with [[Constructing_Components#A_very_simple_Counter|Listing 3 and Listing 4]] previously tackled because they have to run with OpenOffice.org now. This little example uses a registered external module (counter.uno.so build from counter.cxx) and a main program (countermain.cxx) which uses it.
 +
 
The generated counter, like ProfUnoLifeTime, is able to run even if OpenOffice isn't running.  
 
The generated counter, like ProfUnoLifeTime, is able to run even if OpenOffice isn't running.  
MainCounter in the Figure below is the binary program file to run to test the example. There is no direct arrow between MainCounter and Counter.uno.so, indicating that they are independent of each other : if MainCounter want something from Counter.uno.so, it has to ask to cppuhelper (in other words to Openoffice). This example has been done previously without the cppuhelper, but the intention is to demonstrate the use of cppuhelper in this specific situation.
+
MainCounter in the Figure below is the binary program file to run to test the example. There is no direct arrow between MainCounter and Counter.uno.so, indicating that they are independent of each other : if MainCounter want something from Counter.uno.so, it has to ask to cppuhelper (in other words to Openoffice).  
 +
 
 +
== Make Dependency ==
 +
 
 +
We shows with the figure below what tools are involved in the construction of the counter :
  
 
[[Image:MakefileCounterEx.png]]
 
[[Image:MakefileCounterEx.png]]
  
The make dependency for this example (see Figure above) is more complicated than previously, because of the two cpp source files : counter.cxx and countermain.cxx. Please note we have to create a third file in this example : XCounter.idl. The listing of this IDL file is now comprehensive by a reader who have studied [[chapter 10]] :
+
The make dependency for this example (see Figure above) is more complicated than [[previously]], because of the two cpp source files : counter.cxx and countermain.cxx. Please note we have to create a third file in this example : XCounter.idl.  
 +
== IDL File ==
 +
The listing of this IDL file is now comprehensive by a reader who have studied [[chapter 10]] :
  
 
<pre>
 
<pre>
Line 33: Line 40:
 
</pre>
 
</pre>
 
This IDL file describe the interface of counter.cxx which will become counter.uno.so (counter.uno.dll under Windows), a library file after compilation. But again you call one of the four method not directly but through cppuhelper.  
 
This IDL file describe the interface of counter.cxx which will become counter.uno.so (counter.uno.dll under Windows), a library file after compilation. But again you call one of the four method not directly but through cppuhelper.  
 +
 +
== The counter class ==
 +
We give the listing of the counter class :
  
 
<code>[cpp]
 
<code>[cpp]
Line 199: Line 209:
 
}
 
}
 
</code>
 
</code>
 +
This is a lot of code compared with [[Constructing_Components#A_very_simple_Counter|Listing 3]]
  
 +
== The countermain program ==
 
<code>[cpp]
 
<code>[cpp]
 
// C++ countermain.cxx
 
// C++ countermain.cxx
Line 257: Line 269:
 
}
 
}
 
</code>
 
</code>
 +
 +
This is a lot of code compared with [[Constructing_Components#A_very_simple_Counter|Listing 4]]
  
 
Return to [[Constructing_Components |Constructing Component]] or to "Using C++ with OOo SDK" [[Using_Cpp_with_the_OOo_SDK|main page]]
 
Return to [[Constructing_Components |Constructing Component]] or to "Using C++ with OOo SDK" [[Using_Cpp_with_the_OOo_SDK|main page]]

Revision as of 10:26, 25 May 2006

This example given with the SDK contains two files : counter.cxx and countermain.cxx. These files shows differencies with Listing 3 and Listing 4 previously tackled because they have to run with OpenOffice.org now. This little example uses a registered external module (counter.uno.so build from counter.cxx) and a main program (countermain.cxx) which uses it.

The generated counter, like ProfUnoLifeTime, is able to run even if OpenOffice isn't running. MainCounter in the Figure below is the binary program file to run to test the example. There is no direct arrow between MainCounter and Counter.uno.so, indicating that they are independent of each other : if MainCounter want something from Counter.uno.so, it has to ask to cppuhelper (in other words to Openoffice).

Make Dependency

We shows with the figure below what tools are involved in the construction of the counter :

MakefileCounterEx.png

The make dependency for this example (see Figure above) is more complicated than previously, because of the two cpp source files : counter.cxx and countermain.cxx. Please note we have to create a third file in this example : XCounter.idl.

IDL File

The listing of this IDL file is now comprehensive by a reader who have studied chapter 10 :

//Listing 6 The IDL Counter File
// IDL
#include <com/sun/star/uno/XInterface.idl>

module foo
{
	/**
	 * Interface to count things. 
	 */
	interface XCountable : com::sun::star::uno::XInterface
	{
		long getCount();
		void setCount( [in] long nCount );
		long increment();
		long decrement();
	};

	service Counter
	{
		// exported interface:
		interface XCountable;
	};
};

This IDL file describe the interface of counter.cxx which will become counter.uno.so (counter.uno.dll under Windows), a library file after compilation. But again you call one of the four method not directly but through cppuhelper.

The counter class

We give the listing of the counter class :

[cpp] // C++ //================================================================================================== class MyCounterImpl : public XCountable , public XServiceInfo { // to obtain other services if needed Reference< XMultiServiceFactory > m_xServiceManager;

sal_Int32 m_nRefCount; sal_Int32 m_nCount;

public: MyCounterImpl( const Reference< XMultiServiceFactory > & xServiceManager ) : m_xServiceManager( xServiceManager ), m_nRefCount( 0 ) { printf( "< MyCounterImpl ctor called >\n" ); } ~MyCounterImpl() { printf( "< MyCounterImpl dtor called >\n" ); }

// XInterface implementation virtual void SAL_CALL acquire() throw () { ++m_nRefCount; } virtual void SAL_CALL release() throw () { if (! --m_nRefCount) delete this; } virtual Any SAL_CALL queryInterface( const Type & rType ) throw (RuntimeException) { return cppu::queryInterface(rType,

       		static_cast< XInterface* >( static_cast< XServiceInfo* >( this ) ),
       		static_cast< XCountable* >( this ),
                       static_cast< XServiceInfo* >( this ) ); }

// XServiceInfo implementation

   virtual OUString SAL_CALL getImplementationName(  ) throw(RuntimeException);
   virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
   virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) throw(RuntimeException);
   static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(  );

// XCountable implementation virtual sal_Int32 SAL_CALL getCount() throw (RuntimeException) { return m_nCount; } virtual void SAL_CALL setCount( sal_Int32 nCount ) throw (RuntimeException) { m_nCount = nCount; } virtual sal_Int32 SAL_CALL increment() throw (RuntimeException) { return (++m_nCount); } virtual sal_Int32 SAL_CALL decrement() throw (RuntimeException) { return (--m_nCount); } };

//************************************************************************* OUString SAL_CALL MyCounterImpl::getImplementationName( ) throw(RuntimeException) { return OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ); }

//************************************************************************* sal_Bool SAL_CALL MyCounterImpl::supportsService( const OUString& ServiceName ) throw(RuntimeException) { Sequence< OUString > aSNL = getSupportedServiceNames(); const OUString * pArray = aSNL.getArray(); for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) if( pArray[i] == ServiceName ) return sal_True; return sal_False; }

//************************************************************************* Sequence<OUString> SAL_CALL MyCounterImpl::getSupportedServiceNames( ) throw(RuntimeException) { return getSupportedServiceNames_Static(); }

//************************************************************************* Sequence<OUString> SAL_CALL MyCounterImpl::getSupportedServiceNames_Static( ) { OUString aName( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) ); return Sequence< OUString >( &aName, 1 ); }

/**

* Function to create a new component instance; is needed by factory helper implementation.
* @param xMgr service manager to if the components needs other component instances
*/

Reference< XInterface > SAL_CALL MyCounterImpl_create( const Reference< XMultiServiceFactory > & xMgr ) { return Reference< XCountable >( new MyCounterImpl( xMgr ) ); }

//################################################################################################## //#### EXPORTED #################################################################################### //################################################################################################## /**

* Gives the environment this component belongs to.
*/

extern "C" void SAL_CALL component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv) { *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; } /**

* This function creates an implementation section in the registry and another subkey
*
* for each supported service.
* @param pServiceManager   the service manager
* @param pRegistryKey      the registry key
*/

extern "C" sal_Bool SAL_CALL component_writeInfo(void * pServiceManager, void * pRegistryKey) { sal_Bool result = sal_False;

if (pRegistryKey) { try { Reference< XRegistryKey > xNewKey( reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM("/" IMPLNAME "/UNO/SERVICES") ) ) );

const Sequence< OUString > & rSNL = MyCounterImpl::getSupportedServiceNames_Static(); const OUString * pArray = rSNL.getConstArray(); for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) xNewKey->createKey( pArray[nPos] );

return sal_True; } catch (InvalidRegistryException &) { // we should not ignore exceptions } } return result; } /**

* This function is called to get service factories for an implementation.
*
* @param pImplName       name of implementation
* @param pServiceManager a service manager, need for component creation
* @param pRegistryKey    the registry key for this component, need for persistent data
* @return a component factory 
*/

extern "C" void * SAL_CALL component_getFactory(const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey) { void * pRet = 0;

if (rtl_str_compare( pImplName, IMPLNAME ) == 0) { Reference< XSingleServiceFactory > xFactory( createSingleFactory( reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), OUString( RTL_CONSTASCII_USTRINGPARAM(IMPLNAME) ), MyCounterImpl_create, MyCounterImpl::getSupportedServiceNames_Static() ) );

if (xFactory.is()) { xFactory->acquire(); pRet = xFactory.get(); } }

return pRet; } This is a lot of code compared with Listing 3

The countermain program

[cpp] // C++ countermain.cxx int SAL_CALL main(int argc, char **argv) { Reference< XSimpleRegistry > xReg = createSimpleRegistry(); OSL_ENSURE( xReg.is(), "### cannot get service instance of \"com.sun.star.regiystry.SimpleRegistry\"!" );

xReg->open(OUString::createFromAscii("counter.uno.rdb"), sal_False, sal_False); OSL_ENSURE( xReg->isValid(), "### cannot open test registry \"counter.uno.rdb\"!" );

Reference< XComponentContext > xContext = bootstrap_InitialComponentContext(xReg); OSL_ENSURE( xContext.is(), "### cannot creage intial component context!" );

Reference< XMultiComponentFactory > xMgr = xContext->getServiceManager(); OSL_ENSURE( xMgr.is(), "### cannot get initial service manager!" );

// register my counter component Reference< XImplementationRegistration > xImplReg( xMgr->createInstanceWithContext(OUString::createFromAscii("com.sun.star.registry.ImplementationRegistration"), xContext), UNO_QUERY); OSL_ENSURE( xImplReg.is(), "### cannot get service instance of \"com.sun.star.registry.ImplementationRegistration\"!" );

if (xImplReg.is()) { xImplReg->registerImplementation( OUString::createFromAscii("com.sun.star.loader.SharedLibrary"), // loader for component

  1. ifdef UNX
  2. ifdef MACOSX

OUString::createFromAscii("counter.uno.dylib"), // component location

  1. else

OUString::createFromAscii("counter.uno.so"), // component location

  1. endif
  2. else

OUString::createFromAscii("counter.uno.dll"), // component location

  1. endif

Reference< XSimpleRegistry >() // registry omitted, // defaulting to service manager registry used );

// get a counter instance Reference< XInterface > xx ; xx = xMgr->createInstanceWithContext(OUString::createFromAscii("foo.Counter"), xContext); Reference< XCountable > xCount( xx, UNO_QUERY ); OSL_ENSURE( xCount.is(), "### cannot get service instance of \"foo.Counter\"!" );

if (xCount.is()) { xCount->setCount( 42 ); fprintf( stdout , "%d," , xCount->getCount() ); fprintf( stdout , "%d," , xCount->increment() ); fprintf( stdout , "%d\n" , xCount->decrement() ); } }

Reference< XComponent >::query( xContext )->dispose(); return 0; }

This is a lot of code compared with Listing 4

Return to Constructing Component or to "Using C++ with OOo SDK" main page

Personal tools