1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_cli_ure.hxx"
32 //ToDo: remove when build with .NET 2
33 #pragma warning(push, 1)
35 #include "uno/environment.hxx"
37 #include "rtl/unload.h"
38 #include "uno/lbnames.h"
39 #include "uno/mapping.hxx"
40 #include "typelib/typedescription.hxx"
41 #include "rtl/ustring.hxx"
43 #include "cli_bridge.h"
44 #include "cli_proxy.h"
45 namespace srr
= System::Runtime::Remoting
;
46 namespace srrp
= System::Runtime::Remoting::Proxies
;
48 #if defined(_MSC_VER) && (_MSC_VER < 1400)
52 namespace cssu
= com::sun::star::uno
;
55 namespace sri
= System::Runtime::InteropServices
;
63 void SAL_CALL
Mapping_acquire( uno_Mapping
* mapping
)
66 Mapping
const * that
= static_cast< Mapping
const * >( mapping
);
67 that
->m_bridge
->acquire();
69 //--------------------------------------------------------------------------------------------------
70 void SAL_CALL
Mapping_release( uno_Mapping
* mapping
)
73 Mapping
const * that
= static_cast< Mapping
const * >( mapping
);
74 that
->m_bridge
->release();
78 //--------------------------------------------------------------------------------------------------
79 void SAL_CALL
Mapping_cli2uno(
80 uno_Mapping
* mapping
, void ** ppOut
,
81 void * pIn
, typelib_InterfaceTypeDescription
* td
)
84 uno_Interface
** ppUnoI
= (uno_Interface
**)ppOut
;
85 intptr_t cliI
= (intptr_t)pIn
;
87 OSL_ENSURE( ppUnoI
&& td
, "### null ptr!" );
91 uno_Interface
* pUnoI
= *(uno_Interface
**)ppUnoI
;
92 (*pUnoI
->release
)( pUnoI
);
97 Mapping
const * that
= static_cast< Mapping
const * >( mapping
);
98 Bridge
* bridge
= that
->m_bridge
;
102 System::Object
* cliObj
= sri::GCHandle::op_Explicit(cliI
).Target
;
103 (*ppOut
)= bridge
->map_cli2uno(cliObj
, (typelib_TypeDescription
*) td
);
106 catch (BridgeRuntimeError
& err
)
108 #if OSL_DEBUG_LEVEL >= 1
111 OUSTR("[cli_uno bridge error] ") + err
.m_message
, RTL_TEXTENCODING_ASCII_US
) );
112 OSL_ENSURE( 0, cstr_msg
.getStr() );
114 (void) err
; // unused
118 //--------------------------------------------------------------------------------------------------
119 void SAL_CALL
Mapping_uno2cli(
120 uno_Mapping
* mapping
, void ** ppOut
,
121 void * pIn
, typelib_InterfaceTypeDescription
* td
)
126 OSL_ENSURE( td
&& ppOut
, "### null ptr!" );
127 OSL_ENSURE( (sizeof(System::Char
) == sizeof(sal_Unicode
))
128 && (sizeof(System::Boolean
) == sizeof(sal_Bool
))
129 && (sizeof(System::SByte
) == sizeof(sal_Int8
))
130 && (sizeof(System::Int16
) == sizeof(sal_Int16
))
131 && (sizeof(System::UInt16
) == sizeof(sal_uInt16
))
132 && (sizeof(System::Int32
) == sizeof(sal_Int32
))
133 && (sizeof(System::UInt32
) == sizeof(sal_uInt32
))
134 && (sizeof(System::Int64
) == sizeof(sal_Int64
))
135 && (sizeof(System::UInt64
) == sizeof(sal_uInt64
))
136 && (sizeof(System::Single
) == sizeof(float))
137 && (sizeof(System::Double
) == sizeof(double)),
138 "[cli_uno bridge] incompatible .NET data types");
139 intptr_t * ppDNetI
= (intptr_t *)ppOut
;
140 uno_Interface
* pUnoI
= (uno_Interface
*)pIn
;
142 Mapping
const * that
= static_cast< Mapping
const * >( mapping
);
143 Bridge
* bridge
= that
->m_bridge
;
147 sri::GCHandle::op_Explicit(ppDNetI
).Free();
152 System::Object
* cliI
= bridge
->map_uno2cli(pUnoI
, td
);
156 ptr
= sri::GCHandle::op_Explicit(sri::GCHandle::Alloc(cliI
))
159 #else /* defined(_WIN64) */ .ToInt64();
162 (*ppOut
)= reinterpret_cast<void*>(ptr
);
165 catch (BridgeRuntimeError
& err
)
167 #if OSL_DEBUG_LEVEL >= 1
168 rtl::OString
cstr_msg(
169 rtl::OUStringToOString(
170 OUSTR("[cli_uno bridge error] ") + err
.m_message
, RTL_TEXTENCODING_ASCII_US
) );
171 OSL_ENSURE( 0, cstr_msg
.getStr() );
173 (void) err
; // unused
178 //__________________________________________________________________________________________________
179 void SAL_CALL
Bridge_free( uno_Mapping
* mapping
)
182 Mapping
* that
= static_cast< Mapping
* >( mapping
);
183 delete that
->m_bridge
;
192 //__________________________________________________________________________________________________
194 I doubt that the the case that the ref count raises from 0 to 1
195 can occur. uno_ext_getMapping returns an acquired mapping. Every time
196 that function is called then a new mapping is created. Following the
197 rules of ref counted objects, then if the ref count is null noone has
198 a reference to the object anymore. Hence noone can call acquire. If someone
199 calls acquire then they must have kept an unacquired pointer which is
202 void Bridge::acquire() const SAL_THROW( () )
204 if (1 == osl_incrementInterlockedCount( &m_ref
))
206 if (m_registered_cli2uno
)
208 uno_Mapping
* mapping
= const_cast<Mapping
*>(&m_cli2uno
);
210 & const_cast<uno_Mapping
*>(mapping
), Bridge_free
, m_uno_cli_env
, (uno_Environment
*)m_uno_env
, 0 );
214 uno_Mapping
* mapping
= const_cast<Mapping
*>(&m_uno2cli
);
216 &mapping
, Bridge_free
, (uno_Environment
*)m_uno_env
, m_uno_cli_env
, 0 );
220 //__________________________________________________________________________________________________
221 void Bridge::release() const SAL_THROW( () )
223 if (! osl_decrementInterlockedCount( &m_ref
))
227 ? const_cast<Mapping
*>(&m_cli2uno
)
228 : const_cast<Mapping
*>(&m_uno2cli
) );
231 //__________________________________________________________________________________________________
233 uno_Environment
* uno_cli_env
, uno_ExtEnvironment
* uno_env
,
234 bool registered_cli2uno
)
236 m_uno_env( uno_env
),
237 m_uno_cli_env( uno_cli_env
),
238 m_registered_cli2uno( registered_cli2uno
)
240 OSL_ASSERT( 0 != m_uno_cli_env
&& 0 != m_uno_env
);
241 (*((uno_Environment
*)m_uno_env
)->acquire
)( (uno_Environment
*)m_uno_env
);
242 (*m_uno_cli_env
->acquire
)( m_uno_cli_env
);
245 m_cli2uno
.acquire
= Mapping_acquire
;
246 m_cli2uno
.release
= Mapping_release
;
247 m_cli2uno
.mapInterface
= Mapping_cli2uno
;
248 m_cli2uno
.m_bridge
= this;
250 m_uno2cli
.acquire
= Mapping_acquire
;
251 m_uno2cli
.release
= Mapping_release
;
252 m_uno2cli
.mapInterface
= Mapping_uno2cli
;
253 m_uno2cli
.m_bridge
= this;
257 //__________________________________________________________________________________________________
258 Bridge::~Bridge() SAL_THROW( () )
260 //System::GC::Collect();
261 (*m_uno_cli_env
->release
)( m_uno_cli_env
);
262 (*((uno_Environment
*)m_uno_env
)->release
)( (uno_Environment
*)m_uno_env
);
267 } //namespace cli_uno
274 //--------------------------------------------------------------------------------------------------
275 void SAL_CALL
cli_env_disposing( uno_Environment
* uno_cli_env
)
278 uno_cli_env
->pContext
= 0;
281 //##################################################################################################
282 void SAL_CALL
uno_initEnvironment( uno_Environment
* uno_cli_env
)
285 //ToDo: remove when compiled with .NET 2
286 #if defined(_MSC_VER) && (_MSC_VER < 1400)
287 __crt_dll_initialize();
290 uno_cli_env
->environmentDisposing
= cli_env_disposing
;
291 uno_cli_env
->pExtEnv
= 0;
292 //Set the console to print Trace messages
293 #if OSL_DEBUG_LEVEL >= 1
294 System::Diagnostics::Trace::get_Listeners()->
295 Add( new System::Diagnostics::TextWriterTraceListener(System::Console::get_Out()));
297 OSL_ASSERT( 0 == uno_cli_env
->pContext
);
299 // We let the Cli_environment leak, since there is no good point where we could destruct it.
300 //dispose is not used because we would have then also synchronize the calls to proxies. If the
301 //Cli_environment is disposed, we must prevent all calls, otherwise we may crash at points
302 //where g_cli_env is accessed.
303 //When we compile the bridge with .NET 2 then we can again hold g_cli_env as a static gcroot
304 //member in a unmanaged class, such as Bridge.
305 CliEnvHolder::g_cli_env
= new Cli_environment();
307 //##################################################################################################
308 void SAL_CALL
uno_ext_getMapping(
309 uno_Mapping
** ppMapping
, uno_Environment
* pFrom
, uno_Environment
* pTo
)
312 OSL_ASSERT( 0 != ppMapping
&& 0 != pFrom
&& 0 != pTo
);
315 (*(*ppMapping
)->release
)( *ppMapping
);
320 OUString
const & from_env_typename
= *reinterpret_cast< OUString
const * >(
322 OUString
const & to_env_typename
= *reinterpret_cast< OUString
const * >(
325 uno_Mapping
* mapping
= 0;
329 if (from_env_typename
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_CLI
) ) &&
330 to_env_typename
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO
) ))
332 Bridge
* bridge
= new Bridge( pFrom
, pTo
->pExtEnv
, true ); // ref count = 1
333 mapping
= &bridge
->m_cli2uno
;
335 &mapping
, Bridge_free
, pFrom
, (uno_Environment
*)pTo
->pExtEnv
, 0 );
337 else if (from_env_typename
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO
) ) &&
338 to_env_typename
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_CLI
) ))
340 Bridge
* bridge
= new Bridge( pTo
, pFrom
->pExtEnv
, false ); // ref count = 1
341 mapping
= &bridge
->m_uno2cli
;
343 &mapping
, Bridge_free
, (uno_Environment
*)pFrom
->pExtEnv
, pTo
, 0 );
346 catch (BridgeRuntimeError
& err
)
348 #if OSL_DEBUG_LEVEL >= 1
351 OUSTR("[cli_uno bridge error] ") + err
.m_message
, RTL_TEXTENCODING_ASCII_US
) );
352 OSL_ENSURE( 0, cstr_msg
.getStr() );
354 (void) err
; // unused
357 *ppMapping
= mapping
;
361 //##################################################################################################
362 sal_Bool SAL_CALL
component_canUnload( TimeValue
* )