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: cli_bridge.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 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_cli_ure.hxx"
35 //ToDo: remove when build with .NET 2
36 #pragma warning(push, 1)
38 #include "uno/environment.hxx"
40 #include "rtl/unload.h"
41 #include "uno/lbnames.h"
42 #include "uno/mapping.hxx"
43 #include "typelib/typedescription.hxx"
44 #include "rtl/ustring.hxx"
46 #include "cli_bridge.h"
47 #include "cli_proxy.h"
48 namespace srr
= System::Runtime::Remoting
;
49 namespace srrp
= System::Runtime::Remoting::Proxies
;
51 #if defined(_MSC_VER) && (_MSC_VER < 1400)
55 namespace cssu
= com::sun::star::uno
;
58 namespace sri
= System::Runtime::InteropServices
;
66 void SAL_CALL
Mapping_acquire( uno_Mapping
* mapping
)
69 Mapping
const * that
= static_cast< Mapping
const * >( mapping
);
70 that
->m_bridge
->acquire();
72 //--------------------------------------------------------------------------------------------------
73 void SAL_CALL
Mapping_release( uno_Mapping
* mapping
)
76 Mapping
const * that
= static_cast< Mapping
const * >( mapping
);
77 that
->m_bridge
->release();
81 //--------------------------------------------------------------------------------------------------
82 void SAL_CALL
Mapping_cli2uno(
83 uno_Mapping
* mapping
, void ** ppOut
,
84 void * pIn
, typelib_InterfaceTypeDescription
* td
)
87 uno_Interface
** ppUnoI
= (uno_Interface
**)ppOut
;
88 intptr_t cliI
= (intptr_t)pIn
;
90 OSL_ENSURE( ppUnoI
&& td
, "### null ptr!" );
94 uno_Interface
* pUnoI
= *(uno_Interface
**)ppUnoI
;
95 (*pUnoI
->release
)( pUnoI
);
100 Mapping
const * that
= static_cast< Mapping
const * >( mapping
);
101 Bridge
* bridge
= that
->m_bridge
;
105 System::Object
* cliObj
= sri::GCHandle::op_Explicit(cliI
).Target
;
106 (*ppOut
)= bridge
->map_cli2uno(cliObj
, (typelib_TypeDescription
*) td
);
109 catch (BridgeRuntimeError
& err
)
111 #if OSL_DEBUG_LEVEL >= 1
114 OUSTR("[cli_uno bridge error] ") + err
.m_message
, RTL_TEXTENCODING_ASCII_US
) );
115 OSL_ENSURE( 0, cstr_msg
.getStr() );
117 (void) err
; // unused
121 //--------------------------------------------------------------------------------------------------
122 void SAL_CALL
Mapping_uno2cli(
123 uno_Mapping
* mapping
, void ** ppOut
,
124 void * pIn
, typelib_InterfaceTypeDescription
* td
)
129 OSL_ENSURE( td
&& ppOut
, "### null ptr!" );
130 OSL_ENSURE( (sizeof(System::Char
) == sizeof(sal_Unicode
))
131 && (sizeof(System::Boolean
) == sizeof(sal_Bool
))
132 && (sizeof(System::SByte
) == sizeof(sal_Int8
))
133 && (sizeof(System::Int16
) == sizeof(sal_Int16
))
134 && (sizeof(System::UInt16
) == sizeof(sal_uInt16
))
135 && (sizeof(System::Int32
) == sizeof(sal_Int32
))
136 && (sizeof(System::UInt32
) == sizeof(sal_uInt32
))
137 && (sizeof(System::Int64
) == sizeof(sal_Int64
))
138 && (sizeof(System::UInt64
) == sizeof(sal_uInt64
))
139 && (sizeof(System::Single
) == sizeof(float))
140 && (sizeof(System::Double
) == sizeof(double)),
141 "[cli_uno bridge] incompatible .NET data types");
142 intptr_t * ppDNetI
= (intptr_t *)ppOut
;
143 uno_Interface
* pUnoI
= (uno_Interface
*)pIn
;
145 Mapping
const * that
= static_cast< Mapping
const * >( mapping
);
146 Bridge
* bridge
= that
->m_bridge
;
150 sri::GCHandle::op_Explicit(ppDNetI
).Free();
155 System::Object
* cliI
= bridge
->map_uno2cli(pUnoI
, td
);
159 ptr
= sri::GCHandle::op_Explicit(sri::GCHandle::Alloc(cliI
))
162 #else /* defined(_WIN64) */ .ToInt64();
165 (*ppOut
)= reinterpret_cast<void*>(ptr
);
168 catch (BridgeRuntimeError
& err
)
170 #if OSL_DEBUG_LEVEL >= 1
171 rtl::OString
cstr_msg(
172 rtl::OUStringToOString(
173 OUSTR("[cli_uno bridge error] ") + err
.m_message
, RTL_TEXTENCODING_ASCII_US
) );
174 OSL_ENSURE( 0, cstr_msg
.getStr() );
176 (void) err
; // unused
181 //__________________________________________________________________________________________________
182 void SAL_CALL
Bridge_free( uno_Mapping
* mapping
)
185 Mapping
* that
= static_cast< Mapping
* >( mapping
);
186 delete that
->m_bridge
;
195 //__________________________________________________________________________________________________
197 I doubt that the the case that the ref count raises from 0 to 1
198 can occur. uno_ext_getMapping returns an acquired mapping. Every time
199 that function is called then a new mapping is created. Following the
200 rules of ref counted objects, then if the ref count is null noone has
201 a reference to the object anymore. Hence noone can call acquire. If someone
202 calls acquire then they must have kept an unacquired pointer which is
205 void Bridge::acquire() const SAL_THROW( () )
207 if (1 == osl_incrementInterlockedCount( &m_ref
))
209 if (m_registered_cli2uno
)
211 uno_Mapping
* mapping
= const_cast<Mapping
*>(&m_cli2uno
);
213 & const_cast<uno_Mapping
*>(mapping
), Bridge_free
, m_uno_cli_env
, (uno_Environment
*)m_uno_env
, 0 );
217 uno_Mapping
* mapping
= const_cast<Mapping
*>(&m_uno2cli
);
219 &mapping
, Bridge_free
, (uno_Environment
*)m_uno_env
, m_uno_cli_env
, 0 );
223 //__________________________________________________________________________________________________
224 void Bridge::release() const SAL_THROW( () )
226 if (! osl_decrementInterlockedCount( &m_ref
))
230 ? const_cast<Mapping
*>(&m_cli2uno
)
231 : const_cast<Mapping
*>(&m_uno2cli
) );
234 //__________________________________________________________________________________________________
236 uno_Environment
* uno_cli_env
, uno_ExtEnvironment
* uno_env
,
237 bool registered_cli2uno
)
239 m_uno_env( uno_env
),
240 m_uno_cli_env( uno_cli_env
),
241 m_registered_cli2uno( registered_cli2uno
)
243 OSL_ASSERT( 0 != m_uno_cli_env
&& 0 != m_uno_env
);
244 (*((uno_Environment
*)m_uno_env
)->acquire
)( (uno_Environment
*)m_uno_env
);
245 (*m_uno_cli_env
->acquire
)( m_uno_cli_env
);
248 m_cli2uno
.acquire
= Mapping_acquire
;
249 m_cli2uno
.release
= Mapping_release
;
250 m_cli2uno
.mapInterface
= Mapping_cli2uno
;
251 m_cli2uno
.m_bridge
= this;
253 m_uno2cli
.acquire
= Mapping_acquire
;
254 m_uno2cli
.release
= Mapping_release
;
255 m_uno2cli
.mapInterface
= Mapping_uno2cli
;
256 m_uno2cli
.m_bridge
= this;
260 //__________________________________________________________________________________________________
261 Bridge::~Bridge() SAL_THROW( () )
263 //System::GC::Collect();
264 (*m_uno_cli_env
->release
)( m_uno_cli_env
);
265 (*((uno_Environment
*)m_uno_env
)->release
)( (uno_Environment
*)m_uno_env
);
270 } //namespace cli_uno
277 //--------------------------------------------------------------------------------------------------
278 void SAL_CALL
cli_env_disposing( uno_Environment
* uno_cli_env
)
281 uno_cli_env
->pContext
= 0;
284 //##################################################################################################
285 void SAL_CALL
uno_initEnvironment( uno_Environment
* uno_cli_env
)
288 //ToDo: remove when compiled with .NET 2
289 #if defined(_MSC_VER) && (_MSC_VER < 1400)
290 __crt_dll_initialize();
293 uno_cli_env
->environmentDisposing
= cli_env_disposing
;
294 uno_cli_env
->pExtEnv
= 0;
295 //Set the console to print Trace messages
296 #if OSL_DEBUG_LEVEL >= 1
297 System::Diagnostics::Trace::get_Listeners()->
298 Add( new System::Diagnostics::TextWriterTraceListener(System::Console::get_Out()));
300 OSL_ASSERT( 0 == uno_cli_env
->pContext
);
302 // We let the Cli_environment leak, since there is no good point where we could destruct it.
303 //dispose is not used because we would have then also synchronize the calls to proxies. If the
304 //Cli_environment is disposed, we must prevent all calls, otherwise we may crash at points
305 //where g_cli_env is accessed.
306 //When we compile the bridge with .NET 2 then we can again hold g_cli_env as a static gcroot
307 //member in a unmanaged class, such as Bridge.
308 CliEnvHolder::g_cli_env
= new Cli_environment();
310 //##################################################################################################
311 void SAL_CALL
uno_ext_getMapping(
312 uno_Mapping
** ppMapping
, uno_Environment
* pFrom
, uno_Environment
* pTo
)
315 OSL_ASSERT( 0 != ppMapping
&& 0 != pFrom
&& 0 != pTo
);
318 (*(*ppMapping
)->release
)( *ppMapping
);
323 OUString
const & from_env_typename
= *reinterpret_cast< OUString
const * >(
325 OUString
const & to_env_typename
= *reinterpret_cast< OUString
const * >(
328 uno_Mapping
* mapping
= 0;
332 if (from_env_typename
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_CLI
) ) &&
333 to_env_typename
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO
) ))
335 Bridge
* bridge
= new Bridge( pFrom
, pTo
->pExtEnv
, true ); // ref count = 1
336 mapping
= &bridge
->m_cli2uno
;
338 &mapping
, Bridge_free
, pFrom
, (uno_Environment
*)pTo
->pExtEnv
, 0 );
340 else if (from_env_typename
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO
) ) &&
341 to_env_typename
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_CLI
) ))
343 Bridge
* bridge
= new Bridge( pTo
, pFrom
->pExtEnv
, false ); // ref count = 1
344 mapping
= &bridge
->m_uno2cli
;
346 &mapping
, Bridge_free
, (uno_Environment
*)pFrom
->pExtEnv
, pTo
, 0 );
349 catch (BridgeRuntimeError
& err
)
351 #if OSL_DEBUG_LEVEL >= 1
354 OUSTR("[cli_uno bridge error] ") + err
.m_message
, RTL_TEXTENCODING_ASCII_US
) );
355 OSL_ENSURE( 0, cstr_msg
.getStr() );
357 (void) err
; // unused
360 *ppMapping
= mapping
;
364 //##################################################################################################
365 sal_Bool SAL_CALL
component_canUnload( TimeValue
* )