1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cppinterfaceproxy.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_bridges.hxx"
35 #include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
37 #include "guardedarray.hxx"
39 #include "bridges/cpp_uno/shared/bridge.hxx"
40 #include "bridges/cpp_uno/shared/vtablefactory.hxx"
42 #include "com/sun/star/uno/XInterface.hpp"
43 #include "osl/diagnose.h"
44 #include "osl/getglobalmutex.hxx"
45 #include "osl/interlck.h"
46 #include "osl/mutex.hxx"
47 #include "rtl/instance.hxx"
48 #include "typelib/typedescription.h"
54 static bridges::cpp_uno::shared::VtableFactory
* pInstance
;
56 #if defined(__GNUG__) && !defined(__MINGW32__)
57 void dso_init(void) __attribute__((constructor
));
58 void dso_exit(void) __attribute__((destructor
));
63 pInstance
= new bridges::cpp_uno::shared::VtableFactory();
75 # pragma init(dso_init)
76 # pragma fini(dso_exit)
83 struct InitVtableFactory
{
84 bridges::cpp_uno::shared::VtableFactory
* operator()() {
89 bridges::cpp_uno::shared::VtableFactory
* getVtableFactory() {
91 bridges::cpp_uno::shared::VtableFactory
, InitVtableFactory
,
92 osl::MutexGuard
, osl::GetGlobalMutex
>::create(
93 InitVtableFactory(), osl::GetGlobalMutex());
98 namespace bridges
{ namespace cpp_uno
{ namespace shared
{
100 void freeCppInterfaceProxy(uno_ExtEnvironment
* pEnv
, void * pInterface
)
102 CppInterfaceProxy
* pThis
= CppInterfaceProxy::castInterfaceToProxy(
104 if (pEnv
!= pThis
->pBridge
->getCppEnv()) {
108 (*pThis
->pBridge
->getUnoEnv()->revokeInterface
)(
109 pThis
->pBridge
->getUnoEnv(), pThis
->pUnoI
);
110 (*pThis
->pUnoI
->release
)( pThis
->pUnoI
);
111 ::typelib_typedescription_release(
112 (typelib_TypeDescription
*)pThis
->pTypeDescr
);
113 pThis
->pBridge
->release();
115 #if OSL_DEBUG_LEVEL > 1
116 *(int *)pInterface
= 0xdeadbabe;
118 pThis
->~CppInterfaceProxy();
119 delete[] reinterpret_cast< char * >(pThis
);
122 com::sun::star::uno::XInterface
* CppInterfaceProxy::create(
123 bridges::cpp_uno::shared::Bridge
* pBridge
, uno_Interface
* pUnoI
,
124 typelib_InterfaceTypeDescription
* pTypeDescr
, rtl::OUString
const & rOId
)
127 typelib_typedescription_complete(
128 reinterpret_cast< typelib_TypeDescription
** >(&pTypeDescr
));
129 bridges::cpp_uno::shared::VtableFactory::Vtables
aVtables(
130 getVtableFactory()->getVtables(pTypeDescr
));
131 bridges::cpp_uno::shared::GuardedArray
< char > pMemory(
133 sizeof (CppInterfaceProxy
)
134 + (aVtables
.count
- 1) * sizeof (void **)]);
135 new(pMemory
.get()) CppInterfaceProxy(pBridge
, pUnoI
, pTypeDescr
, rOId
);
136 CppInterfaceProxy
* pProxy
= reinterpret_cast< CppInterfaceProxy
* >(
138 for (sal_Int32 i
= 0; i
< aVtables
.count
; ++i
) {
139 pProxy
->vtables
[i
] = VtableFactory::mapBlockToVtable(
140 aVtables
.blocks
[i
].start
);
142 return castProxyToInterface(pProxy
);
145 void CppInterfaceProxy::acquireProxy() SAL_THROW(())
147 if (1 == osl_incrementInterlockedCount( &nRef
))
149 // rebirth of proxy zombie
150 // register at cpp env
151 void * pThis
= castProxyToInterface( this );
152 (*pBridge
->getCppEnv()->registerProxyInterface
)(
153 pBridge
->getCppEnv(), &pThis
, freeCppInterfaceProxy
, oid
.pData
,
155 OSL_ASSERT( pThis
== castProxyToInterface( this ) );
159 void CppInterfaceProxy::releaseProxy() SAL_THROW(())
161 if (! osl_decrementInterlockedCount( &nRef
)) // last release
163 // revoke from cpp env
164 (*pBridge
->getCppEnv()->revokeInterface
)(
165 pBridge
->getCppEnv(), castProxyToInterface( this ) );
169 CppInterfaceProxy::CppInterfaceProxy(
170 bridges::cpp_uno::shared::Bridge
* pBridge_
, uno_Interface
* pUnoI_
,
171 typelib_InterfaceTypeDescription
* pTypeDescr_
, rtl::OUString
const & rOId_
)
174 , pBridge( pBridge_
)
176 , pTypeDescr( pTypeDescr_
)
180 ::typelib_typedescription_acquire( (typelib_TypeDescription
*)pTypeDescr
);
181 (*pUnoI
->acquire
)( pUnoI
);
182 (*pBridge
->getUnoEnv()->registerInterface
)(
183 pBridge
->getUnoEnv(), reinterpret_cast< void ** >( &pUnoI
), oid
.pData
,
187 CppInterfaceProxy::~CppInterfaceProxy()
190 com::sun::star::uno::XInterface
* CppInterfaceProxy::castProxyToInterface(
191 CppInterfaceProxy
* pProxy
)
193 return reinterpret_cast< com::sun::star::uno::XInterface
* >(
197 CppInterfaceProxy
* CppInterfaceProxy::castInterfaceToProxy(void * pInterface
)
199 // pInterface == &pProxy->vtables (this emulated offsetof is not truly
201 char const * const base
= reinterpret_cast< char const * >(16);
202 std::ptrdiff_t const offset
= reinterpret_cast< char const * >(
203 &reinterpret_cast< CppInterfaceProxy
const * >(base
)->vtables
) - base
;
204 return reinterpret_cast< CppInterfaceProxy
* >(
205 static_cast< char * >(pInterface
) - offset
);