1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski #if ! defined(COMPHELPER_SERVICEDECL_HXX_INCLUDED) 24*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_HXX_INCLUDED 25*b1cdbd2cSJim Jagielski 26*b1cdbd2cSJim Jagielski #include <comphelper/comphelperdllapi.h> 27*b1cdbd2cSJim Jagielski #include <cppuhelper/implbase1.hxx> 28*b1cdbd2cSJim Jagielski #include <com/sun/star/uno/XComponentContext.hpp> 29*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XServiceInfo.hpp> 30*b1cdbd2cSJim Jagielski #include <com/sun/star/registry/XRegistryKey.hpp> 31*b1cdbd2cSJim Jagielski #include <uno/environment.h> 32*b1cdbd2cSJim Jagielski #include <boost/utility.hpp> 33*b1cdbd2cSJim Jagielski #include <boost/function.hpp> 34*b1cdbd2cSJim Jagielski #include <boost/preprocessor/cat.hpp> 35*b1cdbd2cSJim Jagielski #include <boost/preprocessor/repetition.hpp> 36*b1cdbd2cSJim Jagielski #include <boost/preprocessor/seq/enum.hpp> 37*b1cdbd2cSJim Jagielski 38*b1cdbd2cSJim Jagielski namespace comphelper { 39*b1cdbd2cSJim Jagielski namespace service_decl { 40*b1cdbd2cSJim Jagielski 41*b1cdbd2cSJim Jagielski class ServiceDecl; 42*b1cdbd2cSJim Jagielski 43*b1cdbd2cSJim Jagielski namespace detail { 44*b1cdbd2cSJim Jagielski namespace css = ::com::sun::star; 45*b1cdbd2cSJim Jagielski typedef ::boost::function3< 46*b1cdbd2cSJim Jagielski css::uno::Reference<css::uno::XInterface> /* return */, 47*b1cdbd2cSJim Jagielski ServiceDecl const&, 48*b1cdbd2cSJim Jagielski css::uno::Sequence<css::uno::Any> const&, 49*b1cdbd2cSJim Jagielski css::uno::Reference<css::uno::XComponentContext> const&> CreateFuncF; 50*b1cdbd2cSJim Jagielski } 51*b1cdbd2cSJim Jagielski 52*b1cdbd2cSJim Jagielski /** Class to declare a service implementation. There is no need to implement 53*b1cdbd2cSJim Jagielski lang::XServiceInfo nor lang::XInitialization anymore. 54*b1cdbd2cSJim Jagielski The declaration can be done in various ways, the (simplest) form is 55*b1cdbd2cSJim Jagielski 56*b1cdbd2cSJim Jagielski <pre> 57*b1cdbd2cSJim Jagielski class MyClass : public cppu::WeakImplHelper2<XInterface1, XInterface2> { 58*b1cdbd2cSJim Jagielski public: 59*b1cdbd2cSJim Jagielski MyClass( uno::Reference<uno::XComponentContext> const& xContext ) 60*b1cdbd2cSJim Jagielski [...] 61*b1cdbd2cSJim Jagielski }; 62*b1cdbd2cSJim Jagielski [...] 63*b1cdbd2cSJim Jagielski namespace sdecl = comphelper::service_decl; 64*b1cdbd2cSJim Jagielski sdecl::ServiceDecl const myDecl( 65*b1cdbd2cSJim Jagielski sdecl::class_<MyClass>(), 66*b1cdbd2cSJim Jagielski "my.unique.implementation.name", 67*b1cdbd2cSJim Jagielski "MyServiceSpec1;MyServiceSpec2" ); 68*b1cdbd2cSJim Jagielski </pre> 69*b1cdbd2cSJim Jagielski 70*b1cdbd2cSJim Jagielski If the service demands initialization by arguments, the implementation 71*b1cdbd2cSJim Jagielski class has to define a constructor taking both arguments and component 72*b1cdbd2cSJim Jagielski context: 73*b1cdbd2cSJim Jagielski 74*b1cdbd2cSJim Jagielski <pre> 75*b1cdbd2cSJim Jagielski class MyClass : public cppu::WeakImplHelper2<XInterface1, XInterface2> { 76*b1cdbd2cSJim Jagielski public: 77*b1cdbd2cSJim Jagielski MyClass( uno::Sequence<uno::Any> const& args, 78*b1cdbd2cSJim Jagielski uno::Reference<uno:XComponentContext> const& xContext ) 79*b1cdbd2cSJim Jagielski [...] 80*b1cdbd2cSJim Jagielski }; 81*b1cdbd2cSJim Jagielski [...] 82*b1cdbd2cSJim Jagielski namespace sdecl = comphelper::service_decl; 83*b1cdbd2cSJim Jagielski sdecl::ServiceDecl const myDecl( 84*b1cdbd2cSJim Jagielski sdecl::class_<MyClass, sdecl::with_args<true> >(), 85*b1cdbd2cSJim Jagielski "my.unique.implementation.name", 86*b1cdbd2cSJim Jagielski "MyServiceSpec1;MyServiceSpec2" ); 87*b1cdbd2cSJim Jagielski </pre> 88*b1cdbd2cSJim Jagielski 89*b1cdbd2cSJim Jagielski Additionally, there is the possibility to process some code after creation, 90*b1cdbd2cSJim Jagielski e.g. to add the newly created object as a listener or perform aggregation 91*b1cdbd2cSJim Jagielski (C++-UNO only): 92*b1cdbd2cSJim Jagielski 93*b1cdbd2cSJim Jagielski <pre> 94*b1cdbd2cSJim Jagielski uno::Reference<uno::XInterface> somePostProcCode( MyClass * p ); 95*b1cdbd2cSJim Jagielski [...] 96*b1cdbd2cSJim Jagielski namespace sdecl = comphelper::service_decl; 97*b1cdbd2cSJim Jagielski sdecl::ServiceDecl const myDecl( 98*b1cdbd2cSJim Jagielski sdecl::class_<MyClass, ... >(&somePostProcCode), 99*b1cdbd2cSJim Jagielski "my.unique.implementation.name", 100*b1cdbd2cSJim Jagielski "MyServiceSpec1;MyServiceSpec2" ); 101*b1cdbd2cSJim Jagielski </pre> 102*b1cdbd2cSJim Jagielski 103*b1cdbd2cSJim Jagielski In the latter case, somePostProcCode gets the yet unacquired "raw" pointer. 104*b1cdbd2cSJim Jagielski */ 105*b1cdbd2cSJim Jagielski class COMPHELPER_DLLPUBLIC ServiceDecl : private ::boost::noncopyable 106*b1cdbd2cSJim Jagielski { 107*b1cdbd2cSJim Jagielski public: 108*b1cdbd2cSJim Jagielski /** Ctor for multiple supported service names. 109*b1cdbd2cSJim Jagielski 110*b1cdbd2cSJim Jagielski @param implClass implementation class description 111*b1cdbd2cSJim Jagielski @param pImplName implementation name 112*b1cdbd2cSJim Jagielski @param pSupportedServiceNames supported service names 113*b1cdbd2cSJim Jagielski @param cDelim delimiter for supported service names 114*b1cdbd2cSJim Jagielski */ 115*b1cdbd2cSJim Jagielski template <typename ImplClassT> ServiceDecl(ImplClassT const & implClass,char const * pImplName,char const * pSupportedServiceNames,char cDelim=';')116*b1cdbd2cSJim Jagielski ServiceDecl( ImplClassT const& implClass, 117*b1cdbd2cSJim Jagielski char const* pImplName, 118*b1cdbd2cSJim Jagielski char const* pSupportedServiceNames, char cDelim = ';' ) 119*b1cdbd2cSJim Jagielski : m_createFunc(implClass.m_createFunc), 120*b1cdbd2cSJim Jagielski m_pImplName(pImplName), 121*b1cdbd2cSJim Jagielski m_pServiceNames(pSupportedServiceNames), 122*b1cdbd2cSJim Jagielski m_cDelim(cDelim) {} 123*b1cdbd2cSJim Jagielski 124*b1cdbd2cSJim Jagielski /// @internal gets called by component_getFactoryHelper() 125*b1cdbd2cSJim Jagielski void * getFactory( sal_Char const* pImplName ) const; 126*b1cdbd2cSJim Jagielski 127*b1cdbd2cSJim Jagielski /// @return supported service names 128*b1cdbd2cSJim Jagielski ::com::sun::star::uno::Sequence< ::rtl::OUString> 129*b1cdbd2cSJim Jagielski getSupportedServiceNames() const; 130*b1cdbd2cSJim Jagielski 131*b1cdbd2cSJim Jagielski /// @return whether name is in set of supported service names 132*b1cdbd2cSJim Jagielski bool supportsService( ::rtl::OUString const& name ) const; 133*b1cdbd2cSJim Jagielski 134*b1cdbd2cSJim Jagielski /// @return implementation name 135*b1cdbd2cSJim Jagielski ::rtl::OUString getImplementationName() const; 136*b1cdbd2cSJim Jagielski 137*b1cdbd2cSJim Jagielski private: 138*b1cdbd2cSJim Jagielski class Factory; 139*b1cdbd2cSJim Jagielski friend class Factory; 140*b1cdbd2cSJim Jagielski 141*b1cdbd2cSJim Jagielski detail::CreateFuncF const m_createFunc; 142*b1cdbd2cSJim Jagielski char const* const m_pImplName; 143*b1cdbd2cSJim Jagielski char const* const m_pServiceNames; 144*b1cdbd2cSJim Jagielski char const m_cDelim; 145*b1cdbd2cSJim Jagielski }; 146*b1cdbd2cSJim Jagielski 147*b1cdbd2cSJim Jagielski /** To specify whether the implementation class expects arguments 148*b1cdbd2cSJim Jagielski (uno::Sequence<uno::Any>). 149*b1cdbd2cSJim Jagielski */ 150*b1cdbd2cSJim Jagielski template <bool> struct with_args; 151*b1cdbd2cSJim Jagielski 152*b1cdbd2cSJim Jagielski /// @internal 153*b1cdbd2cSJim Jagielski namespace detail { 154*b1cdbd2cSJim Jagielski template <typename ImplT> 155*b1cdbd2cSJim Jagielski class OwnServiceImpl 156*b1cdbd2cSJim Jagielski : public ImplT, 157*b1cdbd2cSJim Jagielski private ::boost::noncopyable 158*b1cdbd2cSJim Jagielski { 159*b1cdbd2cSJim Jagielski typedef ImplT BaseT; 160*b1cdbd2cSJim Jagielski 161*b1cdbd2cSJim Jagielski public: OwnServiceImpl(ServiceDecl const & rServiceDecl,css::uno::Sequence<css::uno::Any> const & args,css::uno::Reference<css::uno::XComponentContext> const & xContext)162*b1cdbd2cSJim Jagielski OwnServiceImpl( 163*b1cdbd2cSJim Jagielski ServiceDecl const& rServiceDecl, 164*b1cdbd2cSJim Jagielski css::uno::Sequence<css::uno::Any> const& args, 165*b1cdbd2cSJim Jagielski css::uno::Reference<css::uno::XComponentContext> const& xContext ) 166*b1cdbd2cSJim Jagielski :BaseT(args, xContext), m_rServiceDecl(rServiceDecl) {} OwnServiceImpl(ServiceDecl const & rServiceDecl,css::uno::Reference<css::uno::XComponentContext> const & xContext)167*b1cdbd2cSJim Jagielski OwnServiceImpl( 168*b1cdbd2cSJim Jagielski ServiceDecl const& rServiceDecl, 169*b1cdbd2cSJim Jagielski css::uno::Reference<css::uno::XComponentContext> const& xContext ) 170*b1cdbd2cSJim Jagielski : BaseT(xContext), m_rServiceDecl(rServiceDecl) {} 171*b1cdbd2cSJim Jagielski 172*b1cdbd2cSJim Jagielski // XServiceInfo getImplementationName()173*b1cdbd2cSJim Jagielski virtual ::rtl::OUString SAL_CALL getImplementationName() 174*b1cdbd2cSJim Jagielski throw (css::uno::RuntimeException) { 175*b1cdbd2cSJim Jagielski return m_rServiceDecl.getImplementationName(); 176*b1cdbd2cSJim Jagielski } supportsService(::rtl::OUString const & name)177*b1cdbd2cSJim Jagielski virtual sal_Bool SAL_CALL supportsService( ::rtl::OUString const& name ) 178*b1cdbd2cSJim Jagielski throw (css::uno::RuntimeException) { 179*b1cdbd2cSJim Jagielski return m_rServiceDecl.supportsService(name); 180*b1cdbd2cSJim Jagielski } 181*b1cdbd2cSJim Jagielski virtual css::uno::Sequence< ::rtl::OUString> getSupportedServiceNames()182*b1cdbd2cSJim Jagielski SAL_CALL getSupportedServiceNames() throw (css::uno::RuntimeException) { 183*b1cdbd2cSJim Jagielski return m_rServiceDecl.getSupportedServiceNames(); 184*b1cdbd2cSJim Jagielski } 185*b1cdbd2cSJim Jagielski 186*b1cdbd2cSJim Jagielski private: 187*b1cdbd2cSJim Jagielski ServiceDecl const& m_rServiceDecl; 188*b1cdbd2cSJim Jagielski }; 189*b1cdbd2cSJim Jagielski 190*b1cdbd2cSJim Jagielski template <typename ImplT> 191*b1cdbd2cSJim Jagielski class ServiceImpl : public OwnServiceImpl< ::cppu::ImplInheritanceHelper1<ImplT,css::lang::XServiceInfo> > 192*b1cdbd2cSJim Jagielski { 193*b1cdbd2cSJim Jagielski typedef OwnServiceImpl< ::cppu::ImplInheritanceHelper1<ImplT,css::lang::XServiceInfo> > ServiceImpl_BASE; 194*b1cdbd2cSJim Jagielski public: ServiceImpl(ServiceDecl const & rServiceDecl,css::uno::Sequence<css::uno::Any> const & args,css::uno::Reference<css::uno::XComponentContext> const & xContext)195*b1cdbd2cSJim Jagielski ServiceImpl( 196*b1cdbd2cSJim Jagielski ServiceDecl const& rServiceDecl, 197*b1cdbd2cSJim Jagielski css::uno::Sequence<css::uno::Any> const& args, 198*b1cdbd2cSJim Jagielski css::uno::Reference<css::uno::XComponentContext> const& xContext ) 199*b1cdbd2cSJim Jagielski : ServiceImpl_BASE(rServiceDecl, args, xContext) {} ServiceImpl(ServiceDecl const & rServiceDecl,css::uno::Reference<css::uno::XComponentContext> const & xContext)200*b1cdbd2cSJim Jagielski ServiceImpl( 201*b1cdbd2cSJim Jagielski ServiceDecl const& rServiceDecl, 202*b1cdbd2cSJim Jagielski css::uno::Reference<css::uno::XComponentContext> const& xContext ) 203*b1cdbd2cSJim Jagielski : ServiceImpl_BASE(rServiceDecl, xContext) {} 204*b1cdbd2cSJim Jagielski }; 205*b1cdbd2cSJim Jagielski 206*b1cdbd2cSJim Jagielski template <typename ServiceImplT> 207*b1cdbd2cSJim Jagielski struct PostProcessDefault { 208*b1cdbd2cSJim Jagielski css::uno::Reference<css::uno::XInterface> operator ()comphelper::service_decl::detail::PostProcessDefault209*b1cdbd2cSJim Jagielski operator()( ServiceImplT * p ) const { 210*b1cdbd2cSJim Jagielski return static_cast<css::lang::XServiceInfo *>(p); 211*b1cdbd2cSJim Jagielski } 212*b1cdbd2cSJim Jagielski }; 213*b1cdbd2cSJim Jagielski 214*b1cdbd2cSJim Jagielski template <typename ImplT, typename PostProcessFuncT, typename WithArgsT> 215*b1cdbd2cSJim Jagielski struct CreateFunc; 216*b1cdbd2cSJim Jagielski 217*b1cdbd2cSJim Jagielski template <typename ImplT, typename PostProcessFuncT> 218*b1cdbd2cSJim Jagielski struct CreateFunc<ImplT, PostProcessFuncT, with_args<false> > { 219*b1cdbd2cSJim Jagielski PostProcessFuncT const m_postProcessFunc; CreateFunccomphelper::service_decl::detail::CreateFunc220*b1cdbd2cSJim Jagielski explicit CreateFunc( PostProcessFuncT const& postProcessFunc ) 221*b1cdbd2cSJim Jagielski : m_postProcessFunc(postProcessFunc) {} 222*b1cdbd2cSJim Jagielski 223*b1cdbd2cSJim Jagielski css::uno::Reference<css::uno::XInterface> operator ()comphelper::service_decl::detail::CreateFunc224*b1cdbd2cSJim Jagielski operator()( ServiceDecl const& rServiceDecl, 225*b1cdbd2cSJim Jagielski css::uno::Sequence<css::uno::Any> const&, 226*b1cdbd2cSJim Jagielski css::uno::Reference<css::uno::XComponentContext> 227*b1cdbd2cSJim Jagielski const& xContext ) const 228*b1cdbd2cSJim Jagielski { 229*b1cdbd2cSJim Jagielski return m_postProcessFunc( 230*b1cdbd2cSJim Jagielski new ImplT( rServiceDecl, xContext ) ); 231*b1cdbd2cSJim Jagielski } 232*b1cdbd2cSJim Jagielski }; 233*b1cdbd2cSJim Jagielski 234*b1cdbd2cSJim Jagielski template <typename ImplT, typename PostProcessFuncT> 235*b1cdbd2cSJim Jagielski struct CreateFunc<ImplT, PostProcessFuncT, with_args<true> > { 236*b1cdbd2cSJim Jagielski PostProcessFuncT const m_postProcessFunc; CreateFunccomphelper::service_decl::detail::CreateFunc237*b1cdbd2cSJim Jagielski explicit CreateFunc( PostProcessFuncT const& postProcessFunc ) 238*b1cdbd2cSJim Jagielski : m_postProcessFunc(postProcessFunc) {} 239*b1cdbd2cSJim Jagielski 240*b1cdbd2cSJim Jagielski css::uno::Reference<css::uno::XInterface> operator ()comphelper::service_decl::detail::CreateFunc241*b1cdbd2cSJim Jagielski operator()( ServiceDecl const& rServiceDecl, 242*b1cdbd2cSJim Jagielski css::uno::Sequence<css::uno::Any> const& args, 243*b1cdbd2cSJim Jagielski css::uno::Reference<css::uno::XComponentContext> 244*b1cdbd2cSJim Jagielski const& xContext ) const 245*b1cdbd2cSJim Jagielski { 246*b1cdbd2cSJim Jagielski return m_postProcessFunc( 247*b1cdbd2cSJim Jagielski new ImplT( rServiceDecl, args, xContext ) ); 248*b1cdbd2cSJim Jagielski } 249*b1cdbd2cSJim Jagielski }; 250*b1cdbd2cSJim Jagielski 251*b1cdbd2cSJim Jagielski } // namespace detail 252*b1cdbd2cSJim Jagielski 253*b1cdbd2cSJim Jagielski /** Defines a service implementation class. 254*b1cdbd2cSJim Jagielski 255*b1cdbd2cSJim Jagielski @tpl ImplT_ service implementation class 256*b1cdbd2cSJim Jagielski @WithArgsT whether the implementation class ctor expects arguments 257*b1cdbd2cSJim Jagielski (uno::Sequence<uno::Any>, uno::Reference<uno::XComponentContext>) 258*b1cdbd2cSJim Jagielski or just (uno::Reference<uno::XComponentContext>) 259*b1cdbd2cSJim Jagielski */ 260*b1cdbd2cSJim Jagielski template <typename ImplT_, typename WithArgsT = with_args<false> > 261*b1cdbd2cSJim Jagielski struct serviceimpl_base { 262*b1cdbd2cSJim Jagielski typedef ImplT_ ImplT; 263*b1cdbd2cSJim Jagielski 264*b1cdbd2cSJim Jagielski detail::CreateFuncF const m_createFunc; 265*b1cdbd2cSJim Jagielski 266*b1cdbd2cSJim Jagielski typedef detail::PostProcessDefault<ImplT> PostProcessDefaultT; 267*b1cdbd2cSJim Jagielski 268*b1cdbd2cSJim Jagielski /** Default ctor. Implementation class without args, expecting 269*b1cdbd2cSJim Jagielski component context as single argument. 270*b1cdbd2cSJim Jagielski */ serviceimpl_basecomphelper::service_decl::serviceimpl_base271*b1cdbd2cSJim Jagielski serviceimpl_base() : m_createFunc( 272*b1cdbd2cSJim Jagielski detail::CreateFunc<ImplT, PostProcessDefaultT, WithArgsT>( 273*b1cdbd2cSJim Jagielski PostProcessDefaultT() ) ) {} 274*b1cdbd2cSJim Jagielski 275*b1cdbd2cSJim Jagielski /** Ctor to pass a post processing function/functor. 276*b1cdbd2cSJim Jagielski 277*b1cdbd2cSJim Jagielski @tpl PostProcessDefaultT let your compiler deduce this 278*b1cdbd2cSJim Jagielski @param postProcessFunc function/functor that gets the yet unacquired 279*b1cdbd2cSJim Jagielski ImplT_ pointer returning a 280*b1cdbd2cSJim Jagielski uno::Reference<uno::XInterface> 281*b1cdbd2cSJim Jagielski */ 282*b1cdbd2cSJim Jagielski template <typename PostProcessFuncT> serviceimpl_basecomphelper::service_decl::serviceimpl_base283*b1cdbd2cSJim Jagielski explicit serviceimpl_base( PostProcessFuncT const& postProcessFunc ) 284*b1cdbd2cSJim Jagielski : m_createFunc( detail::CreateFunc<ImplT, PostProcessFuncT, WithArgsT>( 285*b1cdbd2cSJim Jagielski postProcessFunc ) ) {} 286*b1cdbd2cSJim Jagielski }; 287*b1cdbd2cSJim Jagielski 288*b1cdbd2cSJim Jagielski template <typename ImplT_, typename WithArgsT = with_args<false> > 289*b1cdbd2cSJim Jagielski struct class_ : public serviceimpl_base< detail::ServiceImpl<ImplT_>, WithArgsT > 290*b1cdbd2cSJim Jagielski { 291*b1cdbd2cSJim Jagielski typedef serviceimpl_base< detail::ServiceImpl<ImplT_>, WithArgsT > baseT; 292*b1cdbd2cSJim Jagielski /** Default ctor. Implementation class without args, expecting 293*b1cdbd2cSJim Jagielski component context as single argument. 294*b1cdbd2cSJim Jagielski */ class_comphelper::service_decl::class_295*b1cdbd2cSJim Jagielski class_() : baseT() {} 296*b1cdbd2cSJim Jagielski template <typename PostProcessFuncT> 297*b1cdbd2cSJim Jagielski /** Ctor to pass a post processing function/functor. 298*b1cdbd2cSJim Jagielski 299*b1cdbd2cSJim Jagielski @tpl PostProcessDefaultT let your compiler deduce this 300*b1cdbd2cSJim Jagielski @param postProcessFunc function/functor that gets the yet unacquired 301*b1cdbd2cSJim Jagielski ImplT_ pointer returning a 302*b1cdbd2cSJim Jagielski uno::Reference<uno::XInterface> 303*b1cdbd2cSJim Jagielski */ class_comphelper::service_decl::class_304*b1cdbd2cSJim Jagielski explicit class_( PostProcessFuncT const& postProcessFunc ) : baseT( postProcessFunc ) {} 305*b1cdbd2cSJim Jagielski }; 306*b1cdbd2cSJim Jagielski 307*b1cdbd2cSJim Jagielski // 308*b1cdbd2cSJim Jagielski // component_... helpers with arbitrary service declarations: 309*b1cdbd2cSJim Jagielski // 310*b1cdbd2cSJim Jagielski 311*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_getFactory(z_, n_, unused_) \ 312*b1cdbd2cSJim Jagielski if (pRet == 0) \ 313*b1cdbd2cSJim Jagielski pRet = BOOST_PP_CAT(s, n_).getFactory(pImplName); 314*b1cdbd2cSJim Jagielski 315*b1cdbd2cSJim Jagielski /** The following preprocessor repetitions generate functions like 316*b1cdbd2cSJim Jagielski 317*b1cdbd2cSJim Jagielski <pre> 318*b1cdbd2cSJim Jagielski inline void * component_getFactoryHelper( 319*b1cdbd2cSJim Jagielski sal_Char const* pImplName, 320*b1cdbd2cSJim Jagielski ::com::sun::star::lang::XMultiServiceFactory *, 321*b1cdbd2cSJim Jagielski ::com::sun::star::registry::XRegistryKey * xRegistryKey, 322*b1cdbd2cSJim Jagielski ServiceDecl const& s0, ServiceDecl const& s1, ... ); 323*b1cdbd2cSJim Jagielski </pre> 324*b1cdbd2cSJim Jagielski 325*b1cdbd2cSJim Jagielski which call on the passed service declarations. 326*b1cdbd2cSJim Jagielski 327*b1cdbd2cSJim Jagielski The maximum number of service declarations can be set by defining 328*b1cdbd2cSJim Jagielski COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS; its default is 8. 329*b1cdbd2cSJim Jagielski */ 330*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_make(z_, n_, unused_) \ 331*b1cdbd2cSJim Jagielski inline void * component_getFactoryHelper( \ 332*b1cdbd2cSJim Jagielski sal_Char const* pImplName, \ 333*b1cdbd2cSJim Jagielski ::com::sun::star::lang::XMultiServiceFactory *, \ 334*b1cdbd2cSJim Jagielski ::com::sun::star::registry::XRegistryKey *, \ 335*b1cdbd2cSJim Jagielski BOOST_PP_ENUM_PARAMS(n_, ServiceDecl const& s) ) \ 336*b1cdbd2cSJim Jagielski { \ 337*b1cdbd2cSJim Jagielski void * pRet = 0; \ 338*b1cdbd2cSJim Jagielski BOOST_PP_REPEAT(n_, COMPHELPER_SERVICEDECL_getFactory, ~) \ 339*b1cdbd2cSJim Jagielski return pRet; \ 340*b1cdbd2cSJim Jagielski } 341*b1cdbd2cSJim Jagielski 342*b1cdbd2cSJim Jagielski #if ! defined(COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS) 343*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS 8 344*b1cdbd2cSJim Jagielski #endif 345*b1cdbd2cSJim Jagielski 346*b1cdbd2cSJim Jagielski BOOST_PP_REPEAT_FROM_TO(1, COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS, 347*b1cdbd2cSJim Jagielski COMPHELPER_SERVICEDECL_make, ~) 348*b1cdbd2cSJim Jagielski 349*b1cdbd2cSJim Jagielski #undef COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS 350*b1cdbd2cSJim Jagielski #undef COMPHELPER_SERVICEDECL_make 351*b1cdbd2cSJim Jagielski #undef COMPHELPER_SERVICEDECL_getFactory 352*b1cdbd2cSJim Jagielski 353*b1cdbd2cSJim Jagielski } // namespace service_decl 354*b1cdbd2cSJim Jagielski } // namespace comphelper 355*b1cdbd2cSJim Jagielski 356*b1cdbd2cSJim Jagielski /** The following preprocessor macro generates the C access functions, 357*b1cdbd2cSJim Jagielski that are used to initialize and register the components of a 358*b1cdbd2cSJim Jagielski shared library object. 359*b1cdbd2cSJim Jagielski 360*b1cdbd2cSJim Jagielski If you have, say, written a lib that contains three distinct 361*b1cdbd2cSJim Jagielski components, each with its own ServiceDecl object, you might want 362*b1cdbd2cSJim Jagielski to employ the following code: 363*b1cdbd2cSJim Jagielski 364*b1cdbd2cSJim Jagielski <pre> 365*b1cdbd2cSJim Jagielski // must reside outside _any_ namespace 366*b1cdbd2cSJim Jagielski COMPHELPER_SERVICEDECL_EXPORTS3(yourServiceDecl1, 367*b1cdbd2cSJim Jagielski yourServiceDecl2, 368*b1cdbd2cSJim Jagielski yourServiceDecl3); 369*b1cdbd2cSJim Jagielski </pre> 370*b1cdbd2cSJim Jagielski 371*b1cdbd2cSJim Jagielski For your convenience, the COMPHELPER_SERVICEDECL_EXPORTS<N> macro 372*b1cdbd2cSJim Jagielski comes pre-defined up to N=8, if you should need more arguments, 373*b1cdbd2cSJim Jagielski call COMPHELPER_SERVICEDECL_make_exports directly, like this: 374*b1cdbd2cSJim Jagielski 375*b1cdbd2cSJim Jagielski <pre> 376*b1cdbd2cSJim Jagielski // must reside outside _any_ namespace 377*b1cdbd2cSJim Jagielski COMPHELPER_SERVICEDECL_make_exports((yourServiceDecl1)(yourServiceDecl2)...(yourServiceDeclN)); 378*b1cdbd2cSJim Jagielski </pre> 379*b1cdbd2cSJim Jagielski 380*b1cdbd2cSJim Jagielski Note the missing colons between the bracketed arguments. 381*b1cdbd2cSJim Jagielski */ 382*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_make_exports(varargs_ ) \ 383*b1cdbd2cSJim Jagielski extern "C" \ 384*b1cdbd2cSJim Jagielski { \ 385*b1cdbd2cSJim Jagielski SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( const sal_Char** ppEnvTypeName, \ 386*b1cdbd2cSJim Jagielski uno_Environment** /*ppEnv*/ ) \ 387*b1cdbd2cSJim Jagielski { \ 388*b1cdbd2cSJim Jagielski *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; \ 389*b1cdbd2cSJim Jagielski } \ 390*b1cdbd2cSJim Jagielski \ 391*b1cdbd2cSJim Jagielski SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( sal_Char const* pImplName, \ 392*b1cdbd2cSJim Jagielski ::com::sun::star::lang::XMultiServiceFactory* pServiceManager, \ 393*b1cdbd2cSJim Jagielski ::com::sun::star::registry::XRegistryKey* pRegistryKey ) \ 394*b1cdbd2cSJim Jagielski { \ 395*b1cdbd2cSJim Jagielski return component_getFactoryHelper( pImplName, pServiceManager, \ 396*b1cdbd2cSJim Jagielski pRegistryKey, \ 397*b1cdbd2cSJim Jagielski BOOST_PP_SEQ_ENUM(varargs_) ); \ 398*b1cdbd2cSJim Jagielski } \ 399*b1cdbd2cSJim Jagielski } 400*b1cdbd2cSJim Jagielski 401*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS1(comp0_) \ 402*b1cdbd2cSJim Jagielski COMPHELPER_SERVICEDECL_make_exports((comp0_)) 403*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS2(comp0_,comp1_) \ 404*b1cdbd2cSJim Jagielski COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)) 405*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS3(comp0_,comp1_,comp2_) \ 406*b1cdbd2cSJim Jagielski COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)) 407*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS4(comp0_,comp1_,comp2_,comp3_) \ 408*b1cdbd2cSJim Jagielski COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)) 409*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS5(comp0_,comp1_,comp2_,comp3_,comp4_) \ 410*b1cdbd2cSJim Jagielski COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)) 411*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS6(comp0_,comp1_,comp2_,comp3_,comp4_,comp5_) \ 412*b1cdbd2cSJim Jagielski COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_)) 413*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS7(comp0_,comp1_,comp2_,comp3_,comp4_,comp5_,comp6_) \ 414*b1cdbd2cSJim Jagielski COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_)(comp6_)) 415*b1cdbd2cSJim Jagielski #define COMPHELPER_SERVICEDECL_EXPORTS8(comp0_,comp1_,comp2_,comp3_,comp4_,comp5_,comp6_,comp7_) \ 416*b1cdbd2cSJim Jagielski COMPHELPER_SERVICEDECL_make_exports((comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_)(comp6_)(comp7_)) 417*b1cdbd2cSJim Jagielski 418*b1cdbd2cSJim Jagielski #endif // ! defined(COMPHELPER_SERVICEDECL_HXX_INCLUDED) 419*b1cdbd2cSJim Jagielski 420