xref: /AOO41X/main/bridges/source/jni_uno/jni_java2uno.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_bridges.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <sal/alloca.h>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include "jni_bridge.h"
34*cdf0e10cSrcweir //#include "jni_finalizer.h"
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir #include <algorithm>
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir using namespace ::rtl;
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir namespace jni_uno
44*cdf0e10cSrcweir {
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir //______________________________________________________________________________
47*cdf0e10cSrcweir jobject Bridge::map_to_java(
48*cdf0e10cSrcweir     JNI_context const & jni,
49*cdf0e10cSrcweir     uno_Interface * pUnoI, JNI_interface_type_info const * info ) const
50*cdf0e10cSrcweir {
51*cdf0e10cSrcweir     // get oid
52*cdf0e10cSrcweir     rtl_uString * pOid = 0;
53*cdf0e10cSrcweir     (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI );
54*cdf0e10cSrcweir     OSL_ASSERT( 0 != pOid );
55*cdf0e10cSrcweir     OUString oid( pOid, SAL_NO_ACQUIRE );
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir     // opt getRegisteredInterface()
58*cdf0e10cSrcweir     JLocalAutoRef jo_oid( jni, ustring_to_jstring( jni, oid.pData ) );
59*cdf0e10cSrcweir     jvalue args[ 2 ];
60*cdf0e10cSrcweir     args[ 0 ].l = jo_oid.get();
61*cdf0e10cSrcweir     args[ 1 ].l = info->m_type;
62*cdf0e10cSrcweir     jobject jo_iface = jni->CallObjectMethodA(
63*cdf0e10cSrcweir         m_jni_info->m_object_java_env,
64*cdf0e10cSrcweir         m_jni_info->m_method_IEnvironment_getRegisteredInterface, args );
65*cdf0e10cSrcweir     jni.ensure_no_exception();
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir     if (0 == jo_iface) // no registered iface
68*cdf0e10cSrcweir     {
69*cdf0e10cSrcweir         // register uno interface
70*cdf0e10cSrcweir         (*m_uno_env->registerInterface)(
71*cdf0e10cSrcweir             m_uno_env, reinterpret_cast< void ** >( &pUnoI ),
72*cdf0e10cSrcweir             oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir         // create java and register java proxy
75*cdf0e10cSrcweir         jvalue args2[ 7 ];
76*cdf0e10cSrcweir         acquire();
77*cdf0e10cSrcweir         args2[ 0 ].j = reinterpret_cast< sal_Int64 >( this );
78*cdf0e10cSrcweir         (*pUnoI->acquire)( pUnoI );
79*cdf0e10cSrcweir         args2[ 1 ].l = m_jni_info->m_object_java_env;
80*cdf0e10cSrcweir         args2[ 2 ].j = reinterpret_cast< sal_Int64 >( pUnoI );
81*cdf0e10cSrcweir         typelib_typedescription_acquire( info->m_td.get() );
82*cdf0e10cSrcweir         args2[ 3 ].j = reinterpret_cast< sal_Int64 >( info->m_td.get() );
83*cdf0e10cSrcweir         args2[ 4 ].l = info->m_type;
84*cdf0e10cSrcweir         args2[ 5 ].l = jo_oid.get();
85*cdf0e10cSrcweir         args2[ 6 ].l = info->m_proxy_ctor;
86*cdf0e10cSrcweir         jo_iface = jni->CallStaticObjectMethodA(
87*cdf0e10cSrcweir             m_jni_info->m_class_JNI_proxy,
88*cdf0e10cSrcweir             m_jni_info->m_method_JNI_proxy_create, args2 );
89*cdf0e10cSrcweir         jni.ensure_no_exception();
90*cdf0e10cSrcweir     }
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir     OSL_ASSERT( 0 != jo_iface );
93*cdf0e10cSrcweir     return jo_iface;
94*cdf0e10cSrcweir }
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir //______________________________________________________________________________
98*cdf0e10cSrcweir void Bridge::handle_uno_exc( JNI_context const & jni, uno_Any * uno_exc ) const
99*cdf0e10cSrcweir {
100*cdf0e10cSrcweir     if (typelib_TypeClass_EXCEPTION == uno_exc->pType->eTypeClass)
101*cdf0e10cSrcweir     {
102*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
103*cdf0e10cSrcweir         // append java stack trace to Message member
104*cdf0e10cSrcweir         reinterpret_cast< ::com::sun::star::uno::Exception * >(
105*cdf0e10cSrcweir             uno_exc->pData )->Message += jni.get_stack_trace();
106*cdf0e10cSrcweir #endif
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
109*cdf0e10cSrcweir         {
110*cdf0e10cSrcweir         OUStringBuffer buf( 128 );
111*cdf0e10cSrcweir         buf.appendAscii(
112*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("exception occured java->uno: [") );
113*cdf0e10cSrcweir         buf.append( OUString::unacquired( &uno_exc->pType->pTypeName ) );
114*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
115*cdf0e10cSrcweir         buf.append(
116*cdf0e10cSrcweir             reinterpret_cast< ::com::sun::star::uno::Exception const * >(
117*cdf0e10cSrcweir                 uno_exc->pData )->Message );
118*cdf0e10cSrcweir         OString cstr_msg(
119*cdf0e10cSrcweir             OUStringToOString(
120*cdf0e10cSrcweir                 buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
121*cdf0e10cSrcweir         OSL_TRACE( cstr_msg.getStr() );
122*cdf0e10cSrcweir         }
123*cdf0e10cSrcweir #endif
124*cdf0e10cSrcweir         // signal exception
125*cdf0e10cSrcweir         jvalue java_exc;
126*cdf0e10cSrcweir         try
127*cdf0e10cSrcweir         {
128*cdf0e10cSrcweir             map_to_java(
129*cdf0e10cSrcweir                 jni, &java_exc, uno_exc->pData, uno_exc->pType, 0,
130*cdf0e10cSrcweir                 true /* in */, false /* no out */ );
131*cdf0e10cSrcweir         }
132*cdf0e10cSrcweir         catch (...)
133*cdf0e10cSrcweir         {
134*cdf0e10cSrcweir             uno_any_destruct( uno_exc, 0 );
135*cdf0e10cSrcweir             throw;
136*cdf0e10cSrcweir         }
137*cdf0e10cSrcweir         uno_any_destruct( uno_exc, 0 );
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir         JLocalAutoRef jo_exc( jni, java_exc.l );
140*cdf0e10cSrcweir         jint res = jni->Throw( (jthrowable) jo_exc.get() );
141*cdf0e10cSrcweir         if (0 != res)
142*cdf0e10cSrcweir         {
143*cdf0e10cSrcweir             // call toString()
144*cdf0e10cSrcweir             JLocalAutoRef jo_descr(
145*cdf0e10cSrcweir                 jni, jni->CallObjectMethodA(
146*cdf0e10cSrcweir                     jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) );
147*cdf0e10cSrcweir             jni.ensure_no_exception();
148*cdf0e10cSrcweir             OUStringBuffer buf( 128 );
149*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
150*cdf0e10cSrcweir                                  "throwing java exception failed: ") );
151*cdf0e10cSrcweir             buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
152*cdf0e10cSrcweir             buf.append( jni.get_stack_trace() );
153*cdf0e10cSrcweir             throw BridgeRuntimeError( buf.makeStringAndClear() );
154*cdf0e10cSrcweir         }
155*cdf0e10cSrcweir     }
156*cdf0e10cSrcweir     else
157*cdf0e10cSrcweir     {
158*cdf0e10cSrcweir         OUString message(
159*cdf0e10cSrcweir             OUSTR("thrown exception is no uno exception: ") +
160*cdf0e10cSrcweir             OUString::unacquired( &uno_exc->pType->pTypeName ) +
161*cdf0e10cSrcweir             jni.get_stack_trace() );
162*cdf0e10cSrcweir         uno_any_destruct( uno_exc, 0 );
163*cdf0e10cSrcweir         throw BridgeRuntimeError( message );
164*cdf0e10cSrcweir     }
165*cdf0e10cSrcweir }
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir union largest
168*cdf0e10cSrcweir {
169*cdf0e10cSrcweir     sal_Int64 n;
170*cdf0e10cSrcweir     double d;
171*cdf0e10cSrcweir     void * p;
172*cdf0e10cSrcweir     uno_Any a;
173*cdf0e10cSrcweir };
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir //______________________________________________________________________________
176*cdf0e10cSrcweir jobject Bridge::call_uno(
177*cdf0e10cSrcweir     JNI_context const & jni,
178*cdf0e10cSrcweir     uno_Interface * pUnoI, typelib_TypeDescription * member_td,
179*cdf0e10cSrcweir     typelib_TypeDescriptionReference * return_type,
180*cdf0e10cSrcweir     sal_Int32 nParams, typelib_MethodParameter const * pParams,
181*cdf0e10cSrcweir     jobjectArray jo_args /* may be 0 */ ) const
182*cdf0e10cSrcweir {
183*cdf0e10cSrcweir     // return mem
184*cdf0e10cSrcweir     sal_Int32 return_size;
185*cdf0e10cSrcweir     switch (return_type->eTypeClass) {
186*cdf0e10cSrcweir     case typelib_TypeClass_VOID:
187*cdf0e10cSrcweir         return_size = 0;
188*cdf0e10cSrcweir         break;
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir     case typelib_TypeClass_STRUCT:
191*cdf0e10cSrcweir     case typelib_TypeClass_EXCEPTION:
192*cdf0e10cSrcweir         return_size = std::max(
193*cdf0e10cSrcweir             TypeDescr(return_type).get()->nSize,
194*cdf0e10cSrcweir             static_cast< sal_Int32 >(sizeof (largest)));
195*cdf0e10cSrcweir         break;
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir     default:
198*cdf0e10cSrcweir         return_size = sizeof (largest);
199*cdf0e10cSrcweir         break;
200*cdf0e10cSrcweir     }
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA
203*cdf0e10cSrcweir     char * mem = (char *) malloc(
204*cdf0e10cSrcweir #else
205*cdf0e10cSrcweir     char * mem = (char *) alloca(
206*cdf0e10cSrcweir #endif
207*cdf0e10cSrcweir         (nParams * sizeof (void *)) +
208*cdf0e10cSrcweir         return_size + (nParams * sizeof (largest)) );
209*cdf0e10cSrcweir     void ** uno_args = (void **) mem;
210*cdf0e10cSrcweir     void * uno_ret = return_size == 0 ? 0 : (mem + (nParams * sizeof (void *)));
211*cdf0e10cSrcweir     largest * uno_args_mem = (largest *)
212*cdf0e10cSrcweir         (mem + (nParams * sizeof (void *)) + return_size);
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir     OSL_ASSERT( (0 == nParams) || (nParams == jni->GetArrayLength( jo_args )) );
215*cdf0e10cSrcweir     for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
216*cdf0e10cSrcweir     {
217*cdf0e10cSrcweir         typelib_MethodParameter const & param = pParams[ nPos ];
218*cdf0e10cSrcweir         typelib_TypeDescriptionReference * type = param.pTypeRef;
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir         uno_args[ nPos ] = &uno_args_mem[ nPos ];
221*cdf0e10cSrcweir         if (typelib_TypeClass_STRUCT == type->eTypeClass ||
222*cdf0e10cSrcweir             typelib_TypeClass_EXCEPTION == type->eTypeClass)
223*cdf0e10cSrcweir         {
224*cdf0e10cSrcweir             TypeDescr td( type );
225*cdf0e10cSrcweir             if (sal::static_int_cast< sal_uInt32 >(td.get()->nSize)
226*cdf0e10cSrcweir                 > sizeof (largest))
227*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA
228*cdf0e10cSrcweir                 uno_args[ nPos ] = malloc( td.get()->nSize );
229*cdf0e10cSrcweir #else
230*cdf0e10cSrcweir                 uno_args[ nPos ] = alloca( td.get()->nSize );
231*cdf0e10cSrcweir #endif
232*cdf0e10cSrcweir         }
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir         if (param.bIn)
235*cdf0e10cSrcweir         {
236*cdf0e10cSrcweir             try
237*cdf0e10cSrcweir             {
238*cdf0e10cSrcweir                 JLocalAutoRef jo_arg(
239*cdf0e10cSrcweir                     jni, jni->GetObjectArrayElement( jo_args, nPos ) );
240*cdf0e10cSrcweir                 jni.ensure_no_exception();
241*cdf0e10cSrcweir                 jvalue java_arg;
242*cdf0e10cSrcweir                 java_arg.l = jo_arg.get();
243*cdf0e10cSrcweir                 map_to_uno(
244*cdf0e10cSrcweir                     jni, uno_args[ nPos ], java_arg, type, 0,
245*cdf0e10cSrcweir                     false /* no assign */, sal_False != param.bOut,
246*cdf0e10cSrcweir                     true /* special wrapped integral types */ );
247*cdf0e10cSrcweir             }
248*cdf0e10cSrcweir             catch (...)
249*cdf0e10cSrcweir             {
250*cdf0e10cSrcweir                 // cleanup uno in args
251*cdf0e10cSrcweir                 for ( sal_Int32 n = 0; n < nPos; ++n )
252*cdf0e10cSrcweir                 {
253*cdf0e10cSrcweir                     typelib_MethodParameter const & p = pParams[ n ];
254*cdf0e10cSrcweir                     if (p.bIn)
255*cdf0e10cSrcweir                     {
256*cdf0e10cSrcweir                         uno_type_destructData(
257*cdf0e10cSrcweir                             uno_args[ n ], p.pTypeRef, 0 );
258*cdf0e10cSrcweir                     }
259*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA
260*cdf0e10cSrcweir 		    if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
261*cdf0e10cSrcweir 			free( uno_args[ nPos ] );
262*cdf0e10cSrcweir #endif
263*cdf0e10cSrcweir                 }
264*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA
265*cdf0e10cSrcweir 		free( mem );
266*cdf0e10cSrcweir #endif
267*cdf0e10cSrcweir                 throw;
268*cdf0e10cSrcweir             }
269*cdf0e10cSrcweir         }
270*cdf0e10cSrcweir     }
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir     uno_Any uno_exc_holder;
273*cdf0e10cSrcweir     uno_Any * uno_exc = &uno_exc_holder;
274*cdf0e10cSrcweir     // call binary uno
275*cdf0e10cSrcweir     (*pUnoI->pDispatcher)( pUnoI, member_td, uno_ret, uno_args, &uno_exc );
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir     if (0 == uno_exc)
278*cdf0e10cSrcweir     {
279*cdf0e10cSrcweir         // convert out args; destruct uno args
280*cdf0e10cSrcweir         for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
281*cdf0e10cSrcweir         {
282*cdf0e10cSrcweir             typelib_MethodParameter const & param = pParams[ nPos ];
283*cdf0e10cSrcweir             typelib_TypeDescriptionReference * type = param.pTypeRef;
284*cdf0e10cSrcweir             if (param.bOut)
285*cdf0e10cSrcweir             {
286*cdf0e10cSrcweir                 try
287*cdf0e10cSrcweir                 {
288*cdf0e10cSrcweir                     // get out holder array[ 1 ]
289*cdf0e10cSrcweir                     JLocalAutoRef jo_out_holder(
290*cdf0e10cSrcweir                         jni, jni->GetObjectArrayElement( jo_args, nPos ) );
291*cdf0e10cSrcweir                     jni.ensure_no_exception();
292*cdf0e10cSrcweir                     jvalue java_arg;
293*cdf0e10cSrcweir                     java_arg.l = jo_out_holder.get();
294*cdf0e10cSrcweir                     map_to_java(
295*cdf0e10cSrcweir                         jni, &java_arg, uno_args[ nPos ], type, 0,
296*cdf0e10cSrcweir                         true /* in */, true /* out holder */ );
297*cdf0e10cSrcweir                 }
298*cdf0e10cSrcweir                 catch (...)
299*cdf0e10cSrcweir                 {
300*cdf0e10cSrcweir                     // cleanup further uno args
301*cdf0e10cSrcweir                     for ( sal_Int32 n = nPos; n < nParams; ++n )
302*cdf0e10cSrcweir                     {
303*cdf0e10cSrcweir                         uno_type_destructData(
304*cdf0e10cSrcweir                             uno_args[ n ], pParams[ n ].pTypeRef, 0 );
305*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA
306*cdf0e10cSrcweir 			if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
307*cdf0e10cSrcweir 			    free( uno_args[ nPos ] );
308*cdf0e10cSrcweir #endif
309*cdf0e10cSrcweir                     }
310*cdf0e10cSrcweir                     // cleanup uno return value
311*cdf0e10cSrcweir                     uno_type_destructData( uno_ret, return_type, 0 );
312*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA
313*cdf0e10cSrcweir 		    free( mem );
314*cdf0e10cSrcweir #endif
315*cdf0e10cSrcweir                     throw;
316*cdf0e10cSrcweir                 }
317*cdf0e10cSrcweir             }
318*cdf0e10cSrcweir             if (typelib_TypeClass_DOUBLE < type->eTypeClass &&
319*cdf0e10cSrcweir                 typelib_TypeClass_ENUM != type->eTypeClass) // opt
320*cdf0e10cSrcweir             {
321*cdf0e10cSrcweir                 uno_type_destructData( uno_args[ nPos ], type, 0 );
322*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA
323*cdf0e10cSrcweir 		if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
324*cdf0e10cSrcweir 		    free( uno_args[ nPos ] );
325*cdf0e10cSrcweir #endif
326*cdf0e10cSrcweir             }
327*cdf0e10cSrcweir         }
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir         if (typelib_TypeClass_VOID != return_type->eTypeClass)
330*cdf0e10cSrcweir         {
331*cdf0e10cSrcweir             // convert uno return value
332*cdf0e10cSrcweir             jvalue java_ret;
333*cdf0e10cSrcweir             try
334*cdf0e10cSrcweir             {
335*cdf0e10cSrcweir                 map_to_java(
336*cdf0e10cSrcweir                     jni, &java_ret, uno_ret, return_type, 0,
337*cdf0e10cSrcweir                     true /* in */, false /* no out */,
338*cdf0e10cSrcweir                     true /* special_wrapped_integral_types */ );
339*cdf0e10cSrcweir             }
340*cdf0e10cSrcweir             catch (...)
341*cdf0e10cSrcweir             {
342*cdf0e10cSrcweir                 uno_type_destructData( uno_ret, return_type, 0 );
343*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA
344*cdf0e10cSrcweir 		free( mem );
345*cdf0e10cSrcweir #endif
346*cdf0e10cSrcweir                 throw;
347*cdf0e10cSrcweir             }
348*cdf0e10cSrcweir             if (typelib_TypeClass_DOUBLE < return_type->eTypeClass &&
349*cdf0e10cSrcweir                 typelib_TypeClass_ENUM != return_type->eTypeClass) // opt
350*cdf0e10cSrcweir             {
351*cdf0e10cSrcweir                 uno_type_destructData( uno_ret, return_type, 0 );
352*cdf0e10cSrcweir             }
353*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA
354*cdf0e10cSrcweir 	    free( mem );
355*cdf0e10cSrcweir #endif
356*cdf0e10cSrcweir             return java_ret.l;
357*cdf0e10cSrcweir         }
358*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA
359*cdf0e10cSrcweir 	free( mem );
360*cdf0e10cSrcweir #endif
361*cdf0e10cSrcweir         return 0; // void return
362*cdf0e10cSrcweir     }
363*cdf0e10cSrcweir     else // exception occured
364*cdf0e10cSrcweir     {
365*cdf0e10cSrcweir         // destruct uno in args
366*cdf0e10cSrcweir         for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
367*cdf0e10cSrcweir         {
368*cdf0e10cSrcweir             typelib_MethodParameter const & param = pParams[ nPos ];
369*cdf0e10cSrcweir             if (param.bIn)
370*cdf0e10cSrcweir                 uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 );
371*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA
372*cdf0e10cSrcweir 		if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
373*cdf0e10cSrcweir 		    free( uno_args[ nPos ] );
374*cdf0e10cSrcweir #endif
375*cdf0e10cSrcweir         }
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir         handle_uno_exc( jni, uno_exc );
378*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA
379*cdf0e10cSrcweir 	free( mem );
380*cdf0e10cSrcweir #endif
381*cdf0e10cSrcweir         return 0;
382*cdf0e10cSrcweir     }
383*cdf0e10cSrcweir }
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir }
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir using namespace ::jni_uno;
388*cdf0e10cSrcweir 
389*cdf0e10cSrcweir extern "C"
390*cdf0e10cSrcweir {
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir //------------------------------------------------------------------------------
393*cdf0e10cSrcweir JNIEXPORT jobject
394*cdf0e10cSrcweir JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call(
395*cdf0e10cSrcweir     JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle, jstring,
396*cdf0e10cSrcweir     jstring jo_method, jobjectArray jo_args /* may be 0 */ )
397*cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
398*cdf0e10cSrcweir {
399*cdf0e10cSrcweir     Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
400*cdf0e10cSrcweir     JNI_info const * jni_info = bridge->m_jni_info;
401*cdf0e10cSrcweir     JNI_context jni(
402*cdf0e10cSrcweir         jni_info, jni_env,
403*cdf0e10cSrcweir         static_cast< jobject >(
404*cdf0e10cSrcweir             reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
405*cdf0e10cSrcweir                 bridge->m_java_env->pContext )->getClassLoader() ) );
406*cdf0e10cSrcweir 
407*cdf0e10cSrcweir     OUString method_name;
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir     try
410*cdf0e10cSrcweir     {
411*cdf0e10cSrcweir         method_name = jstring_to_oustring( jni, jo_method );
412*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
413*cdf0e10cSrcweir         {
414*cdf0e10cSrcweir         OUStringBuffer trace_buf( 64 );
415*cdf0e10cSrcweir         trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("java->uno call: ") );
416*cdf0e10cSrcweir         trace_buf.append( method_name );
417*cdf0e10cSrcweir         trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") );
418*cdf0e10cSrcweir         JLocalAutoRef jo_oid(
419*cdf0e10cSrcweir             jni, jni->GetObjectField(
420*cdf0e10cSrcweir                 jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
421*cdf0e10cSrcweir         trace_buf.append( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
422*cdf0e10cSrcweir         OString cstr_msg(
423*cdf0e10cSrcweir             OUStringToOString(
424*cdf0e10cSrcweir                 trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
425*cdf0e10cSrcweir         OSL_TRACE( cstr_msg.getStr() );
426*cdf0e10cSrcweir         }
427*cdf0e10cSrcweir #endif
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir         // special IQueryInterface.queryInterface()
430*cdf0e10cSrcweir         if (method_name.equalsAsciiL(
431*cdf0e10cSrcweir                 RTL_CONSTASCII_STRINGPARAM("queryInterface") ))
432*cdf0e10cSrcweir         {
433*cdf0e10cSrcweir             // oid
434*cdf0e10cSrcweir             JLocalAutoRef jo_oid(
435*cdf0e10cSrcweir                 jni, jni->GetObjectField(
436*cdf0e10cSrcweir                     jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
437*cdf0e10cSrcweir             // type
438*cdf0e10cSrcweir             JLocalAutoRef jo_type(
439*cdf0e10cSrcweir                 jni, jni->GetObjectArrayElement( jo_args, 0 ) );
440*cdf0e10cSrcweir             jni.ensure_no_exception();
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir             JLocalAutoRef jo_type_name(
443*cdf0e10cSrcweir                 jni, jni->GetObjectField(
444*cdf0e10cSrcweir                     jo_type.get(), jni_info->m_field_Type__typeName ) );
445*cdf0e10cSrcweir             if (! jo_type_name.is())
446*cdf0e10cSrcweir             {
447*cdf0e10cSrcweir                 throw BridgeRuntimeError(
448*cdf0e10cSrcweir                     OUSTR("incomplete type object: no type name!") +
449*cdf0e10cSrcweir                     jni.get_stack_trace() );
450*cdf0e10cSrcweir             }
451*cdf0e10cSrcweir             OUString type_name(
452*cdf0e10cSrcweir                 jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
453*cdf0e10cSrcweir             JNI_type_info const * info =
454*cdf0e10cSrcweir                 jni_info->get_type_info( jni, type_name );
455*cdf0e10cSrcweir             if (typelib_TypeClass_INTERFACE != info->m_td.get()->eTypeClass)
456*cdf0e10cSrcweir             {
457*cdf0e10cSrcweir                 throw BridgeRuntimeError(
458*cdf0e10cSrcweir                     OUSTR("queryInterface() call demands an INTERFACE type!") );
459*cdf0e10cSrcweir             }
460*cdf0e10cSrcweir             JNI_interface_type_info const * iface_info =
461*cdf0e10cSrcweir                 static_cast< JNI_interface_type_info const * >( info );
462*cdf0e10cSrcweir 
463*cdf0e10cSrcweir             // getRegisteredInterface() already tested in JNI_proxy:
464*cdf0e10cSrcweir             // perform queryInterface call on binary uno interface
465*cdf0e10cSrcweir             uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
466*cdf0e10cSrcweir                 jni->GetLongField(
467*cdf0e10cSrcweir                     jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir             uno_Any uno_ret;
470*cdf0e10cSrcweir             void * uno_args[] = { &iface_info->m_td.get()->pWeakRef };
471*cdf0e10cSrcweir             uno_Any uno_exc_holder;
472*cdf0e10cSrcweir             uno_Any * uno_exc = &uno_exc_holder;
473*cdf0e10cSrcweir             // call binary uno
474*cdf0e10cSrcweir             (*pUnoI->pDispatcher)(
475*cdf0e10cSrcweir                 pUnoI, jni_info->m_XInterface_queryInterface_td.get(),
476*cdf0e10cSrcweir                 &uno_ret, uno_args, &uno_exc );
477*cdf0e10cSrcweir             if (0 == uno_exc)
478*cdf0e10cSrcweir             {
479*cdf0e10cSrcweir                 jobject jo_ret = 0;
480*cdf0e10cSrcweir                 if (typelib_TypeClass_INTERFACE == uno_ret.pType->eTypeClass)
481*cdf0e10cSrcweir                 {
482*cdf0e10cSrcweir                     uno_Interface * pUnoRet =
483*cdf0e10cSrcweir                         (uno_Interface *) uno_ret.pReserved;
484*cdf0e10cSrcweir                     if (0 != pUnoRet)
485*cdf0e10cSrcweir                     {
486*cdf0e10cSrcweir                         try
487*cdf0e10cSrcweir                         {
488*cdf0e10cSrcweir                             jo_ret =
489*cdf0e10cSrcweir                                 bridge->map_to_java( jni, pUnoRet, iface_info );
490*cdf0e10cSrcweir                         }
491*cdf0e10cSrcweir                         catch (...)
492*cdf0e10cSrcweir                         {
493*cdf0e10cSrcweir                             uno_any_destruct( &uno_ret, 0 );
494*cdf0e10cSrcweir                             throw;
495*cdf0e10cSrcweir                         }
496*cdf0e10cSrcweir                     }
497*cdf0e10cSrcweir                 }
498*cdf0e10cSrcweir                 uno_any_destruct( &uno_ret, 0 );
499*cdf0e10cSrcweir                 return jo_ret;
500*cdf0e10cSrcweir             }
501*cdf0e10cSrcweir             else
502*cdf0e10cSrcweir             {
503*cdf0e10cSrcweir                 bridge->handle_uno_exc( jni, uno_exc );
504*cdf0e10cSrcweir                 return 0;
505*cdf0e10cSrcweir             }
506*cdf0e10cSrcweir         }
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir         typelib_InterfaceTypeDescription * td =
509*cdf0e10cSrcweir             reinterpret_cast< typelib_InterfaceTypeDescription * >(
510*cdf0e10cSrcweir                 jni->GetLongField(
511*cdf0e10cSrcweir                     jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
512*cdf0e10cSrcweir         uno_Interface * pUnoI =
513*cdf0e10cSrcweir             reinterpret_cast< uno_Interface * >(
514*cdf0e10cSrcweir                 jni->GetLongField(
515*cdf0e10cSrcweir                     jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir         typelib_TypeDescriptionReference ** ppAllMembers = td->ppAllMembers;
518*cdf0e10cSrcweir         for ( sal_Int32 nPos = td->nAllMembers; nPos--; )
519*cdf0e10cSrcweir         {
520*cdf0e10cSrcweir             // try to avoid getting typedescription as long as possible,
521*cdf0e10cSrcweir             // because of a Mutex.acquire() in
522*cdf0e10cSrcweir             // typelib_typedescriptionreference_getDescription()
523*cdf0e10cSrcweir             typelib_TypeDescriptionReference * member_type =
524*cdf0e10cSrcweir                 ppAllMembers[ nPos ];
525*cdf0e10cSrcweir 
526*cdf0e10cSrcweir             // check method_name against fully qualified type_name
527*cdf0e10cSrcweir             // of member_type; type_name is of the form
528*cdf0e10cSrcweir             //  <name> "::" <method_name> *(":@" <idx> "," <idx> ":" <name>)
529*cdf0e10cSrcweir             OUString const & type_name =
530*cdf0e10cSrcweir                 OUString::unacquired( &member_type->pTypeName );
531*cdf0e10cSrcweir             sal_Int32 offset = type_name.indexOf( ':' ) + 2;
532*cdf0e10cSrcweir             OSL_ASSERT(
533*cdf0e10cSrcweir                 offset >= 2 && offset < type_name.getLength()
534*cdf0e10cSrcweir                 && type_name[offset - 1] == ':' );
535*cdf0e10cSrcweir             sal_Int32 remainder = type_name.getLength() - offset;
536*cdf0e10cSrcweir             if (typelib_TypeClass_INTERFACE_METHOD == member_type->eTypeClass)
537*cdf0e10cSrcweir             {
538*cdf0e10cSrcweir                 if ((method_name.getLength() == remainder
539*cdf0e10cSrcweir                      || (method_name.getLength() < remainder
540*cdf0e10cSrcweir                          && type_name[offset + method_name.getLength()] == ':'))
541*cdf0e10cSrcweir                     && type_name.match(method_name, offset))
542*cdf0e10cSrcweir                 {
543*cdf0e10cSrcweir                     TypeDescr member_td( member_type );
544*cdf0e10cSrcweir                     typelib_InterfaceMethodTypeDescription * method_td =
545*cdf0e10cSrcweir                         reinterpret_cast<
546*cdf0e10cSrcweir                           typelib_InterfaceMethodTypeDescription * >(
547*cdf0e10cSrcweir                               member_td.get() );
548*cdf0e10cSrcweir                     return bridge->call_uno(
549*cdf0e10cSrcweir                         jni, pUnoI, member_td.get(),
550*cdf0e10cSrcweir                         method_td->pReturnTypeRef,
551*cdf0e10cSrcweir                         method_td->nParams, method_td->pParams,
552*cdf0e10cSrcweir                         jo_args );
553*cdf0e10cSrcweir                 }
554*cdf0e10cSrcweir             }
555*cdf0e10cSrcweir             else // attribute
556*cdf0e10cSrcweir             {
557*cdf0e10cSrcweir                 OSL_ASSERT(
558*cdf0e10cSrcweir                     typelib_TypeClass_INTERFACE_ATTRIBUTE ==
559*cdf0e10cSrcweir                       member_type->eTypeClass );
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir                 if (method_name.getLength() >= 3
562*cdf0e10cSrcweir                     && (method_name.getLength() - 3 == remainder
563*cdf0e10cSrcweir                         || (method_name.getLength() - 3 < remainder
564*cdf0e10cSrcweir                             && type_name[
565*cdf0e10cSrcweir                                 offset + (method_name.getLength() - 3)] == ':'))
566*cdf0e10cSrcweir                     && method_name[1] == 'e' && method_name[2] == 't'
567*cdf0e10cSrcweir                     && rtl_ustr_compare_WithLength(
568*cdf0e10cSrcweir                         type_name.getStr() + offset,
569*cdf0e10cSrcweir                         method_name.getLength() - 3,
570*cdf0e10cSrcweir                         method_name.getStr() + 3,
571*cdf0e10cSrcweir                         method_name.getLength() - 3) == 0)
572*cdf0e10cSrcweir                 {
573*cdf0e10cSrcweir                     if ('g' == method_name[ 0 ])
574*cdf0e10cSrcweir                     {
575*cdf0e10cSrcweir                         TypeDescr member_td( member_type );
576*cdf0e10cSrcweir                         typelib_InterfaceAttributeTypeDescription * attr_td =
577*cdf0e10cSrcweir                             reinterpret_cast<
578*cdf0e10cSrcweir                               typelib_InterfaceAttributeTypeDescription * >(
579*cdf0e10cSrcweir                                   member_td.get() );
580*cdf0e10cSrcweir                         return bridge->call_uno(
581*cdf0e10cSrcweir                             jni, pUnoI, member_td.get(),
582*cdf0e10cSrcweir                             attr_td->pAttributeTypeRef,
583*cdf0e10cSrcweir                             0, 0,
584*cdf0e10cSrcweir                             jo_args );
585*cdf0e10cSrcweir                     }
586*cdf0e10cSrcweir                     else if ('s' == method_name[ 0 ])
587*cdf0e10cSrcweir                     {
588*cdf0e10cSrcweir                         TypeDescr member_td( member_type );
589*cdf0e10cSrcweir                         typelib_InterfaceAttributeTypeDescription * attr_td =
590*cdf0e10cSrcweir                             reinterpret_cast<
591*cdf0e10cSrcweir                               typelib_InterfaceAttributeTypeDescription * >(
592*cdf0e10cSrcweir                                   member_td.get() );
593*cdf0e10cSrcweir                         if (! attr_td->bReadOnly)
594*cdf0e10cSrcweir                         {
595*cdf0e10cSrcweir                             typelib_MethodParameter param;
596*cdf0e10cSrcweir                             param.pTypeRef = attr_td->pAttributeTypeRef;
597*cdf0e10cSrcweir                             param.bIn = sal_True;
598*cdf0e10cSrcweir                             param.bOut = sal_False;
599*cdf0e10cSrcweir                             return bridge->call_uno(
600*cdf0e10cSrcweir                                 jni, pUnoI, member_td.get(),
601*cdf0e10cSrcweir                                 jni_info->m_void_type.getTypeLibType(),
602*cdf0e10cSrcweir                                 1, &param,
603*cdf0e10cSrcweir                                 jo_args );
604*cdf0e10cSrcweir                         }
605*cdf0e10cSrcweir                     }
606*cdf0e10cSrcweir                 }
607*cdf0e10cSrcweir             }
608*cdf0e10cSrcweir         }
609*cdf0e10cSrcweir         // the thing that should not be... no method info found!
610*cdf0e10cSrcweir         OUStringBuffer buf( 64 );
611*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
612*cdf0e10cSrcweir             "calling undeclared function on interface ") );
613*cdf0e10cSrcweir         buf.append( OUString::unacquired(
614*cdf0e10cSrcweir                         &((typelib_TypeDescription *)td)->pTypeName ) );
615*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
616*cdf0e10cSrcweir         buf.append( method_name );
617*cdf0e10cSrcweir         buf.append( jni.get_stack_trace() );
618*cdf0e10cSrcweir         throw BridgeRuntimeError( buf.makeStringAndClear() );
619*cdf0e10cSrcweir     }
620*cdf0e10cSrcweir     catch (BridgeRuntimeError & err)
621*cdf0e10cSrcweir     {
622*cdf0e10cSrcweir         OUStringBuffer buf( 128 );
623*cdf0e10cSrcweir         buf.appendAscii(
624*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("[jni_uno bridge error] "
625*cdf0e10cSrcweir                                        "Java calling UNO method ") );
626*cdf0e10cSrcweir         buf.append( method_name );
627*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
628*cdf0e10cSrcweir         buf.append( err.m_message );
629*cdf0e10cSrcweir         // notify RuntimeException
630*cdf0e10cSrcweir         OString cstr_msg(
631*cdf0e10cSrcweir             OUStringToOString(
632*cdf0e10cSrcweir                 buf.makeStringAndClear(), RTL_TEXTENCODING_JAVA_UTF8 ) );
633*cdf0e10cSrcweir         OSL_ENSURE( 0, cstr_msg.getStr() );
634*cdf0e10cSrcweir         if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
635*cdf0e10cSrcweir             != 0)
636*cdf0e10cSrcweir         {
637*cdf0e10cSrcweir             OSL_ASSERT( false );
638*cdf0e10cSrcweir         }
639*cdf0e10cSrcweir         return 0;
640*cdf0e10cSrcweir     }
641*cdf0e10cSrcweir     catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
642*cdf0e10cSrcweir     {
643*cdf0e10cSrcweir         OString cstr_msg(
644*cdf0e10cSrcweir             OString( RTL_CONSTASCII_STRINGPARAM(
645*cdf0e10cSrcweir                 "[jni_uno bridge error] "
646*cdf0e10cSrcweir                 "attaching current thread to java failed!") ) +
647*cdf0e10cSrcweir             OUStringToOString(
648*cdf0e10cSrcweir                 jni.get_stack_trace(), RTL_TEXTENCODING_JAVA_UTF8 ) );
649*cdf0e10cSrcweir         OSL_ENSURE( 0, cstr_msg.getStr() );
650*cdf0e10cSrcweir         if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
651*cdf0e10cSrcweir             != 0)
652*cdf0e10cSrcweir         {
653*cdf0e10cSrcweir             OSL_ASSERT( false );
654*cdf0e10cSrcweir         }
655*cdf0e10cSrcweir         return 0;
656*cdf0e10cSrcweir     }
657*cdf0e10cSrcweir }
658*cdf0e10cSrcweir 
659*cdf0e10cSrcweir //------------------------------------------------------------------------------
660*cdf0e10cSrcweir JNIEXPORT void
661*cdf0e10cSrcweir JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J(
662*cdf0e10cSrcweir     JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle )
663*cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
664*cdf0e10cSrcweir {
665*cdf0e10cSrcweir     Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
666*cdf0e10cSrcweir     JNI_info const * jni_info = bridge->m_jni_info;
667*cdf0e10cSrcweir     JNI_context jni(
668*cdf0e10cSrcweir         jni_info, jni_env,
669*cdf0e10cSrcweir         static_cast< jobject >(
670*cdf0e10cSrcweir             reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
671*cdf0e10cSrcweir                 bridge->m_java_env->pContext )->getClassLoader() ) );
672*cdf0e10cSrcweir 
673*cdf0e10cSrcweir     uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
674*cdf0e10cSrcweir         jni->GetLongField(
675*cdf0e10cSrcweir             jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
676*cdf0e10cSrcweir     typelib_TypeDescription * td =
677*cdf0e10cSrcweir         reinterpret_cast< typelib_TypeDescription * >(
678*cdf0e10cSrcweir             jni->GetLongField(
679*cdf0e10cSrcweir                 jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
682*cdf0e10cSrcweir     {
683*cdf0e10cSrcweir     JLocalAutoRef jo_oid(
684*cdf0e10cSrcweir         jni, jni->GetObjectField(
685*cdf0e10cSrcweir             jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
686*cdf0e10cSrcweir     OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
687*cdf0e10cSrcweir     OString cstr_msg(
688*cdf0e10cSrcweir         OUStringToOString(
689*cdf0e10cSrcweir             OUSTR("freeing java uno proxy: ") + oid,
690*cdf0e10cSrcweir             RTL_TEXTENCODING_ASCII_US ) );
691*cdf0e10cSrcweir     OSL_TRACE( cstr_msg.getStr() );
692*cdf0e10cSrcweir     }
693*cdf0e10cSrcweir #endif
694*cdf0e10cSrcweir     // revoke from uno env; has already been revoked from java env
695*cdf0e10cSrcweir     (*bridge->m_uno_env->revokeInterface)( bridge->m_uno_env, pUnoI );
696*cdf0e10cSrcweir     // release receiver
697*cdf0e10cSrcweir 	(*pUnoI->release)( pUnoI );
698*cdf0e10cSrcweir     // release typedescription handle
699*cdf0e10cSrcweir     typelib_typedescription_release( td );
700*cdf0e10cSrcweir     // release bridge handle
701*cdf0e10cSrcweir     bridge->release();
702*cdf0e10cSrcweir }
703*cdf0e10cSrcweir 
704*cdf0e10cSrcweir }
705