Difference between revisions of "Counter Example"

From Apache OpenOffice Wiki
Jump to: navigation, search
Line 35: Line 35:
  
 
<code>[cpp]
 
<code>[cpp]
#include <stdio.h>
+
// C++
 
+
#ifndef _RTL_USTRING_HXX_
+
#include <rtl/ustring.hxx>
+
#endif
+
 
+
#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_
+
#include <cppuhelper/queryinterface.hxx> // helper for queryInterface() impl
+
#endif
+
#ifndef _CPPUHELPER_FACTORY_HXX_
+
#include <cppuhelper/factory.hxx> // helper for component factory
+
#endif
+
// generated c++ interfaces
+
 
+
#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
+
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
#endif
+
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
+
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
#endif
+
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
+
#include <com/sun/star/lang/XServiceInfo.hpp>
+
#endif
+
#ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_
+
#include <com/sun/star/registry/XRegistryKey.hpp>
+
#endif
+
#ifndef _FOO_XCOUNTABLE_HPP_
+
#include <foo/XCountable.hpp>
+
#endif
+
 
+
#define SERVICENAME "foo.Counter"
+
#define IMPLNAME "com.sun.star.comp.example.cpp.Counter"
+
 
+
using namespace ::rtl;
+
using namespace ::osl;
+
using namespace ::cppu;
+
using namespace ::com::sun::star::uno;
+
using namespace ::com::sun::star::lang;
+
using namespace ::com::sun::star::registry;
+
using namespace ::foo;
+
 
+
 
+
 
//==================================================================================================
 
//==================================================================================================
 
class MyCounterImpl
 
class MyCounterImpl
Line 95: Line 54:
 
{ printf( "< MyCounterImpl dtor called >\n" ); }
 
{ printf( "< MyCounterImpl dtor called >\n" ); }
  
// XInterface implementation
+
// XInterface implementation
 
virtual void SAL_CALL acquire() throw ()
 
virtual void SAL_CALL acquire() throw ()
 
{ ++m_nRefCount; }
 
{ ++m_nRefCount; }
Line 102: Line 61:
 
virtual Any SAL_CALL queryInterface( const Type & rType ) throw (RuntimeException)
 
virtual Any SAL_CALL queryInterface( const Type & rType ) throw (RuntimeException)
 
{ return cppu::queryInterface(rType,  
 
{ return cppu::queryInterface(rType,  
          static_cast< XInterface* >( static_cast< XServiceInfo* >( this ) ),
+
        static_cast< XInterface* >( static_cast< XServiceInfo* >( this ) ),
          static_cast< XCountable* >( this ),
+
        static_cast< XCountable* >( this ),
                                      static_cast< XServiceInfo* >( this ) ); }
+
                        static_cast< XServiceInfo* >( this ) ); }
  
    // XServiceInfo implementation
+
// XServiceInfo implementation
 
     virtual OUString SAL_CALL getImplementationName(  ) throw(RuntimeException);
 
     virtual OUString SAL_CALL getImplementationName(  ) throw(RuntimeException);
 
     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
 
     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
Line 112: Line 71:
 
     static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(  );
 
     static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(  );
  
// XCountable implementation
+
// XCountable implementation
 
virtual sal_Int32 SAL_CALL getCount() throw (RuntimeException)
 
virtual sal_Int32 SAL_CALL getCount() throw (RuntimeException)
 
{ return m_nCount; }
 
{ return m_nCount; }
Line 155: Line 114:
 
return Sequence< OUString >( &aName, 1 );
 
return Sequence< OUString >( &aName, 1 );
 
}
 
}
 
 
 
  
 
/**
 
/**
Line 168: Line 124:
 
return Reference< XCountable >( new MyCounterImpl( xMgr ) );
 
return Reference< XCountable >( new MyCounterImpl( xMgr ) );
 
}
 
}
 
  
 
//##################################################################################################
 
//##################################################################################################
 
//#### EXPORTED ####################################################################################
 
//#### EXPORTED ####################################################################################
 
//##################################################################################################
 
//##################################################################################################
 
 
 
/**
 
/**
 
  * Gives the environment this component belongs to.
 
  * Gives the environment this component belongs to.
Line 182: Line 135:
 
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
 
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
 
}
 
}
 
 
/**
 
/**
 
  * This function creates an implementation section in the registry and another subkey
 
  * This function creates an implementation section in the registry and another subkey
Line 217: Line 169:
 
return result;
 
return result;
 
}
 
}
 
 
/**
 
/**
 
  * This function is called to get service factories for an implementation.
 
  * This function is called to get service factories for an implementation.
Line 248: Line 199:
 
}
 
}
 
</code>
 
</code>
#include <stdio.h>
 
  
#include <rtl/ustring.hxx>
+
<code>[cpp]
 
+
// C++ countermain.cxx
#include <osl/diagnose.h>
+
 
+
#include <cppuhelper/bootstrap.hxx>
+
#include <cppuhelper/servicefactory.hxx>
+
 
+
// generated c++ interfaces
+
#include <com/sun/star/lang/XComponent.hpp>
+
#include <com/sun/star/registry/XImplementationRegistration.hpp>
+
#include <foo/XCountable.hpp>
+
// added for test
+
//#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
+
//#include <com/sun/star/beans/XPropertySet.hpp>
+
//#include <com/sun/star/frame/XComponentLoader.hpp>
+
 
+
using namespace foo;
+
using namespace cppu;
+
using namespace com::sun::star::uno;
+
using namespace com::sun::star::lang;
+
using namespace com::sun::star::registry;
+
 
+
using namespace ::rtl;
+
// added for test
+
//using namespace com::sun::star::bridge;
+
//using namespace com::sun::star::beans;
+
//using namespace com::sun::star::frame;
+
 
+
 
+
//==================================================================================================
+
 
int SAL_CALL main(int argc, char **argv)
 
int SAL_CALL main(int argc, char **argv)
 
{
 
{
Line 301: Line 223:
 
if (xImplReg.is())
 
if (xImplReg.is())
 
{
 
{
printf("Debut Registery\n");
 
 
xImplReg->registerImplementation(
 
xImplReg->registerImplementation(
 
OUString::createFromAscii("com.sun.star.loader.SharedLibrary"), // loader for component
 
OUString::createFromAscii("com.sun.star.loader.SharedLibrary"), // loader for component
Line 314: Line 235:
 
#endif
 
#endif
 
Reference< XSimpleRegistry >() // registry omitted,
 
Reference< XSimpleRegistry >() // registry omitted,
// defaulting to service manager registry used
+
// defaulting to service manager registry used
 
);
 
);
printf("Fin registery\n");
+
 
// get a counter instance
 
// get a counter instance
 
Reference< XInterface > xx ;
 
Reference< XInterface > xx ;
Line 325: Line 246:
 
if (xCount.is())
 
if (xCount.is())
 
{
 
{
xCount->setCount( 50 );
+
xCount->setCount( 42 );
 
fprintf( stdout , "%d," , xCount->getCount() );
 
fprintf( stdout , "%d," , xCount->getCount() );
 
fprintf( stdout , "%d," , xCount->increment() );
 
fprintf( stdout , "%d," , xCount->increment() );
 
fprintf( stdout , "%d\n" , xCount->decrement() );
 
fprintf( stdout , "%d\n" , xCount->decrement() );
 
}
 
}
// added for test
 
/*
 
xx = xMgr->createInstanceWithContext(OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver"), xContext);
 
Reference< XUnoUrlResolver > resolver( xx, UNO_QUERY );
 
// xx = resolver->resolve( OUString::createFromAscii(
 
//        "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" ) );
 
try
 
        {
 
                xx = Reference< XInterface >(
 
                resolver->resolve( OUString::createFromAscii(
 
        "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" ) ), UNO_QUERY );
 
        }
 
        catch ( Exception &e )
 
        {
 
      printf("Error: cannot establish a connection using '%s':\n      %s\n",
 
                OUString::createFromAscii("uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" ).getStr(),
 
                OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
 
      exit(1);
 
        }
 
// gets the server component context as property of the office component factory
 
Reference< XPropertySet > xPropSet( xx, UNO_QUERY );
 
xPropSet->getPropertyValue( OUString::createFromAscii("DefaultContext") ) >>= xContext;
 
 
 
// gets the service manager from the office
 
Reference< XMultiComponentFactory > xMCF(xContext->getServiceManager() );
 
 
 
Reference< XInterface  > Desktop = xMCF->createInstanceWithContext(
 
OUString::createFromAscii( "com.sun.star.frame.Desktop" ),xContext);
 
if (! Desktop.is()) printf("Pb here !!!!\n"); else printf("I have my Desktop\n");
 
//query for the XComponentLoader interface
 
Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY);
 
  if( rComponentLoader.is() ){
 
        printf( "XComponentloader successfully instanciated\n" );
 
    }
 
 
// end added for test
 
*/
 
 
}
 
}
  
Line 374: Line 256:
 
return 0;
 
return 0;
 
}
 
}
 
<code>[cpp]
 
 
 
</code>
 
</code>
  
 
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:11, 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). This example has been done previously without the cppuhelper, but the intention is to demonstrate the use of cppuhelper in this specific situation.

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 :

//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.

[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; }

[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; }

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

Personal tools