1 /*************************************************************************
7 * last change: $Author: $ $Date: $
9 * The Contents of this file are made available subject to the terms of
10 * either of the following licenses
12 * - GNU Lesser General Public License Version 2.1
13 * - Sun Industry Standards Source License Version 1.1
15 * Sun Microsystems Inc., October, 2000
17 * GNU Lesser General Public License Version 2.1
18 * =============================================
19 * Copyright 2000 by Sun Microsystems, Inc.
20 * 901 San Antonio Road, Palo Alto, CA 94303, USA
22 * This library is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License version 2.1, as published by the Free Software Foundation.
26 * This library is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * Lesser General Public License for more details.
31 * You should have received a copy of the GNU Lesser General Public
32 * License along with this library; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
37 * Sun Industry Standards Source License Version 1.1
38 * =================================================
39 * The contents of this file are subject to the Sun Industry Standards
40 * Source License Version 1.1 (the "License"); You may not use this file
41 * except in compliance with the License. You may obtain a copy of the
42 * License at http://www.openoffice.org/license.html.
44 * Software provided under this License is provided on an "AS IS" basis,
45 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
46 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
47 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
48 * See the License for the specific provisions governing your rights and
49 * obligations concerning the Software.
51 * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
53 * Copyright: 2000 by Sun Microsystems, Inc.
55 * All Rights Reserved.
57 * Contributor(s): _______________________________________
60 ************************************************************************/
64 #include "uno/dispatcher.h"
65 #include "uno/environment.h"
66 #include "uno/lbnames.h"
68 #include "osl/diagnose.h"
69 #include "rtl/unload.h"
70 #include "rtl/ustring.hxx"
72 #include "uno/mapping.hxx"
75 #include "mono/metadata/appdomain.h"
76 #include "mono/metadata/assembly.h"
77 #include "mono/metadata/debug-helpers.h"
78 #include "mono/metadata/object.h"
79 #include "mono/metadata/threads.h"
82 #include "mono_bridge.h"
84 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
86 using namespace ::rtl
;
87 using namespace ::mono_uno
;
91 void SAL_CALL
Mapping_acquire( uno_Mapping
* mapping
)
94 static_cast< Mapping
const * >( mapping
)->m_bridge
->acquire();
97 void SAL_CALL
Mapping_release( uno_Mapping
* mapping
)
100 static_cast< Mapping
const * >( mapping
)->m_bridge
->release();
103 void SAL_CALL
Mapping_map_to_uno(
104 uno_Mapping
* mapping
, void ** ppOut
,
105 void * pIn
, typelib_InterfaceTypeDescription
* td
)
108 uno_Interface
** ppUnoI
= (uno_Interface
**)ppOut
;
111 // FIXME do this here? OSL_ASSERT( sizeof (void *) >= sizeof (guint32))
112 OSL_ENSURE( ppUnoI
&& td
, "### null ptr!" );
116 uno_Interface
* pUnoI
= *ppUnoI
;
117 (*pUnoI
->release
)( pUnoI
);
123 Bridge
const *bridge
=
124 static_cast< Mapping
const * >( mapping
)->m_bridge
;
125 // FIXME any wrapper necessary around mono calls? cf. JNI_guarded_context
126 uno_Interface
* pUnoI
= bridge
->map_to_uno(
127 monoI
, (typelib_TypeDescription
*)td
);
130 catch (BridgeRuntimeError
& err
)
132 #if OSL_DEBUG_LEVEL > 0
135 OUSTR("[mono_uno bridge error] ") + err
.m_message
,
136 RTL_TEXTENCODING_ASCII_US
) );
137 OSL_ENSURE( 0, cstr_msg
.getStr() );
142 void SAL_CALL
Mapping_map_to_mono(
143 uno_Mapping
* mapping
, void ** ppOut
,
144 void * pIn
, typelib_InterfaceTypeDescription
* td
)
147 void ** pMonoI
= ppOut
;
148 uno_Interface
* pUnoI
= (uno_Interface
*)pIn
;
150 OSL_ENSURE( ppOut
&& td
, "### null ptr!" );
154 // FIXME JNI bridge has guarded_context here
155 // FIXME: do the right thing in the managed bridge
156 // mono_gchandle_free( *pMonoI );
163 Bridge
const * bridge
=
164 static_cast< Mapping
const *>( mapping
)->m_bridge
;
165 // FIXME guarded context
166 *ppOut
= (void *)bridge
->map_to_mono(
167 pUnoI
, (typelib_TypeDescription
*)td
);
168 OSL_ASSERT( ppOut
&& *ppOut
);
171 catch (BridgeRuntimeError
& err
)
173 #if OSL_DEBUG_LEVEL >= 1
174 rtl::OString
cstr_msg(
175 rtl::OUStringToOString(
176 OUSTR("[mono_uno bridge error] ") + err
.m_message
,
177 RTL_TEXTENCODING_ASCII_US
) );
178 OSL_ENSURE( 0, cstr_msg
.getStr() );
183 void SAL_CALL
Bridge_free( uno_Mapping
* mapping
)
186 Mapping
* that
= static_cast< Mapping
* >( mapping
);
187 delete that
->m_bridge
;
192 rtl_StandardModuleCount g_moduleCount
= MODULE_COUNT_INIT
;
197 void Bridge::acquire() const SAL_THROW( () )
199 if (1 == osl_incrementInterlockedCount( &m_ref
))
201 if (m_registered_mono2uno
)
203 uno_Mapping
* mapping
= const_cast< Mapping
* >( &m_mono2uno
);
205 &mapping
, Bridge_free
,
206 m_mono_env
, (uno_Environment
*)m_uno_env
, 0 );
210 uno_Mapping
* mapping
= const_cast< Mapping
* >( &m_uno2mono
);
212 &mapping
, Bridge_free
,
213 (uno_Environment
*)m_uno_env
, m_mono_env
, 0 );
218 void Bridge::release() const SAL_THROW( () )
220 if (! osl_decrementInterlockedCount( &m_ref
))
223 m_registered_mono2uno
224 ? const_cast< Mapping
* >( &m_mono2uno
)
225 : const_cast< Mapping
* >( &m_uno2mono
) );
230 DoLoad (MonoDomain
*domain
, char *fullname
)
232 MonoAssemblyName aname
;
233 MonoImageOpenStatus status
;
236 memset (&aname
, 0, sizeof (aname
));
238 strncpy ((char *)aname
.public_key_token
, "ce2cb7e279207b9e", MONO_PUBLIC_KEY_TOKEN_LENGTH
);
239 aname
.name
= "cli_uno_bridge";
245 ass
= mono_assembly_load (&aname
, NULL
, &status
);
246 if (status
!= MONO_IMAGE_OK
)
252 uno_Environment
* mono_env
, uno_ExtEnvironment
* uno_env
,
253 bool registered_mono2uno
)
255 m_uno_env( uno_env
),
256 m_mono_env( mono_env
),
257 m_registered_mono2uno( registered_mono2uno
)
259 MonoDomain
* pDomain
= mono_get_root_domain();
260 // FIXME where is this freed?
261 MonoAssembly
* pAssembly
= DoLoad (pDomain
, "cli_uno_bridge, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ce2cb7e279207b9e");
262 // FIXME and this, is this needed later?
263 MonoClass
* pClass
= mono_class_from_name (
264 (MonoImage
*)mono_assembly_get_image( pAssembly
), "com.sun.star.bridges.mono_uno", "Bridge" );
265 OSL_ASSERT( 0 != pClass
);
266 /* FIXME add args to method description string */
267 MonoMethodDesc
* pMethodDesc
= mono_method_desc_new( ":.ctor", FALSE
);
268 MonoMethod
* pCtor
= mono_method_desc_search_in_class( pMethodDesc
, pClass
);
269 mono_method_desc_free( pMethodDesc
);
270 OSL_ASSERT( 0 != pCtor
);
272 pMethodDesc
= mono_method_desc_new( "Bridge:MapManagedToUno", FALSE
);
273 m_mapManagedToUnoMethod
= mono_method_desc_search_in_class( pMethodDesc
, pClass
);
274 mono_method_desc_free( pMethodDesc
);
275 OSL_ASSERT( 0 != m_mapManagedToUnoMethod
);
277 pMethodDesc
= mono_method_desc_new( "Bridge:MapUnoToManaged", FALSE
);
278 m_mapUnoToManagedMethod
= mono_method_desc_search_in_class( pMethodDesc
, pClass
);
279 mono_method_desc_free( pMethodDesc
);
280 OSL_ASSERT( 0 != m_mapUnoToManagedMethod
);
283 pParams
[0] = &uno_env
;
284 m_managedBridge
= mono_object_new( pDomain
, pClass
);
285 mono_uno::runtime_invoke( pCtor
, m_managedBridge
, pParams
, NULL
,
286 mono_object_get_domain( m_managedBridge
) );
288 OSL_ASSERT( 0 != m_mono_env
&& 0 != m_uno_env
);
289 (*((uno_Environment
*)m_uno_env
)->acquire
)( (uno_Environment
*)m_uno_env
);
290 (*m_mono_env
->acquire
)( m_mono_env
);
293 m_mono2uno
.acquire
= Mapping_acquire
;
294 m_mono2uno
.release
= Mapping_release
;
295 m_mono2uno
.mapInterface
= Mapping_map_to_uno
;
296 m_mono2uno
.m_bridge
= this;
298 m_uno2mono
.acquire
= Mapping_acquire
;
299 m_uno2mono
.release
= Mapping_release
;
300 m_uno2mono
.mapInterface
= Mapping_map_to_mono
;
301 m_uno2mono
.m_bridge
= this;
303 (*g_moduleCount
.modCnt
.acquire
)( &g_moduleCount
.modCnt
);
306 Bridge::~Bridge() SAL_THROW( () )
308 (*m_mono_env
->release
)( m_mono_env
);
309 (*((uno_Environment
*)m_uno_env
)->release
)( (uno_Environment
*)m_uno_env
);
310 // FIXME release managed bridge
312 (*g_moduleCount
.modCnt
.release
)( &g_moduleCount
.modCnt
);
315 void * Bridge::map_to_mono(
316 uno_Interface
*pUnoI
, typelib_TypeDescription
* pTD
) const
318 gpointer pMonoParams
[2];
320 pMonoParams
[0] = &pUnoI
;
321 pMonoParams
[1] = pTD
;
324 mono_uno::runtime_invoke( m_mapUnoToManagedMethod
,
325 m_managedBridge
, pMonoParams
, NULL
,
326 mono_object_get_domain( m_managedBridge
) );
329 uno_Interface
* Bridge::map_to_uno(
330 void * pMonoI
, typelib_TypeDescription
* pTD
) const
332 gpointer pMonoParams
[2];
333 uno_Interface
** ppResult
;
335 pMonoParams
[0] = pMonoI
;
336 pMonoParams
[1] = pTD
;
338 ppResult
= (uno_Interface
**)mono_object_unbox(
339 mono_uno::runtime_invoke( m_mapManagedToUnoMethod
,
340 m_managedBridge
, pMonoParams
, NULL
,
341 mono_object_get_domain( m_managedBridge
) ) );
346 } // namespace mono_uno
350 // void SAL_CALL mono_environmentDisposing( uno_Environment * mono_env )
351 // SAL_THROW_EXTERN_C()
355 void SAL_CALL
uno_initEnvironment( uno_Environment
* mono_env
)
358 // mono_env->environmentDisposing = mono_environmentDisposing;
359 mono_env
->pExtEnv
= 0; /* no extended support */
362 void SAL_CALL
uno_ext_getMapping(
363 uno_Mapping
** ppMapping
, uno_Environment
*pFrom
, uno_Environment
*pTo
)
366 OSL_ASSERT( 0 != ppMapping
&& 0 != pFrom
&& 0 != pTo
);
369 (*(*ppMapping
)->release
)( *ppMapping
);
373 /* FIXME check that mono's and sal's types have matching sizes
374 * like jni_bridge does? */
376 OUString
const & from_env_typename
= OUString::unacquired( &pFrom
->pTypeName
);
377 OUString
const & to_env_typename
= OUString::unacquired( &pTo
->pTypeName
);
379 uno_Mapping
* mapping
= 0;
383 if (from_env_typename
.equalsAsciiL(
384 RTL_CONSTASCII_STRINGPARAM( UNO_LB_CLI
)) &&
385 to_env_typename
.equalsAsciiL(
386 RTL_CONSTASCII_STRINGPARAM( UNO_LB_UNO
)))
389 new Bridge( pFrom
, pTo
->pExtEnv
, true ); // ref count = 1
390 mapping
= &bridge
->m_mono2uno
;
392 &mapping
, Bridge_free
, pFrom
,
393 (uno_Environment
*)pTo
->pExtEnv
, 0);
395 else if (from_env_typename
.equalsAsciiL(
396 RTL_CONSTASCII_STRINGPARAM( UNO_LB_UNO
)) &&
397 to_env_typename
.equalsAsciiL(
398 RTL_CONSTASCII_STRINGPARAM( UNO_LB_CLI
)))
401 new Bridge( pTo
, pFrom
->pExtEnv
, false ); // ref count = 1
402 mapping
= &bridge
->m_uno2mono
;
404 &mapping
, Bridge_free
,
405 (uno_Environment
*)pFrom
->pExtEnv
, pTo
, 0);
408 catch (BridgeRuntimeError
& err
)
410 #if OSL_DEBUG_LEVEL >= 1
413 OUSTR("[mono_uno bridge error] ") + err
.m_message
,
414 RTL_TEXTENCODING_ASCII_US
) );
415 OSL_ENSURE( 0, cstr_msg
.getStr() );
419 *ppMapping
= mapping
;
422 sal_Bool SAL_CALL
component_canUnload( TimeValue
* pTime
)
425 return (*g_moduleCount
.canUnload
)( &g_moduleCount
, pTime
);
431 mono_uno::runtime_invoke (MonoMethod
*method
, void *obj
, void **params
,
432 MonoObject
**exc
, MonoDomain
*domain
)
434 mono_thread_attach( domain
);
435 return mono_runtime_invoke( method
, obj
, params
, exc
);