1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "pyuno_impl.hxx"
25 
26 #include <osl/module.hxx>
27 #include <osl/thread.h>
28 #include <osl/file.hxx>
29 
30 #include <typelib/typedescription.hxx>
31 
32 #include <rtl/strbuf.hxx>
33 #include <rtl/ustrbuf.hxx>
34 #include <rtl/uuid.h>
35 #include <rtl/bootstrap.hxx>
36 
37 #include <uno/current_context.hxx>
38 #include <cppuhelper/bootstrap.hxx>
39 
40 #include <com/sun/star/reflection/XIdlReflection.hpp>
41 #include <com/sun/star/reflection/XIdlClass.hpp>
42 #include <com/sun/star/registry/InvalidRegistryException.hpp>
43 
44 using osl::Module;
45 
46 using rtl::OString;
47 using rtl::OUString;
48 using rtl::OUStringToOString;
49 using rtl::OUStringBuffer;
50 using rtl::OStringBuffer;
51 
52 using com::sun::star::uno::Sequence;
53 using com::sun::star::uno::Reference;
54 using com::sun::star::uno::XInterface;
55 using com::sun::star::uno::Any;
56 using com::sun::star::uno::makeAny;
57 using com::sun::star::uno::UNO_QUERY;
58 using com::sun::star::uno::RuntimeException;
59 using com::sun::star::uno::TypeDescription;
60 using com::sun::star::uno::XComponentContext;
61 using com::sun::star::container::NoSuchElementException;
62 using com::sun::star::reflection::XIdlReflection;
63 using com::sun::star::reflection::XIdlClass;
64 using com::sun::star::script::XInvocation2;
65 
66 using namespace pyuno;
67 
68 namespace {
69 
70 /**
71    @ index of the next to be used member in the initializer list !
72  */
73 sal_Int32 fillStructWithInitializer(
74     const Reference< XInvocation2 > &inv,
75     typelib_CompoundTypeDescription *pCompType,
76     PyObject *initializer,
77     const Runtime &runtime) throw ( RuntimeException )
78 {
79     sal_Int32 nIndex = 0;
80     if( pCompType->pBaseTypeDescription )
81         nIndex = fillStructWithInitializer(
82             inv, pCompType->pBaseTypeDescription, initializer, runtime );
83 
84     sal_Int32 nTupleSize =  PyTuple_Size(initializer);
85     int i;
86     for( i = 0 ; i < pCompType->nMembers ; i ++ )
87     {
88         if( i + nIndex >= nTupleSize )
89         {
90             OUStringBuffer buf;
91             buf.appendAscii( "pyuno._createUnoStructHelper: too few elements in the initializer tuple,");
92             buf.appendAscii( "expected at least " ).append( nIndex + pCompType->nMembers );
93             buf.appendAscii( ", got " ).append( nTupleSize );
94             throw RuntimeException(buf.makeStringAndClear(), Reference< XInterface > ());
95         }
96         PyObject *element = PyTuple_GetItem( initializer, i + nIndex );
97         Any a = runtime.pyObject2Any( element, ACCEPT_UNO_ANY );
98         inv->setValue( pCompType->ppMemberNames[i], a );
99     }
100     return i+nIndex;
101 }
102 
103 OUString getLibDir()
104 {
105     static OUString *pLibDir;
106     if( !pLibDir )
107     {
108         osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
109         if( ! pLibDir )
110         {
111             static OUString libDir;
112 
113             // workarounds the $(ORIGIN) until it is available
114             if( Module::getUrlFromAddress(
115                     reinterpret_cast< oslGenericFunction >(getLibDir), libDir ) )
116             {
117                 libDir = OUString( libDir.getStr(), libDir.lastIndexOf('/' ) );
118                 OUString name ( RTL_CONSTASCII_USTRINGPARAM( "PYUNOLIBDIR" ) );
119                 rtl_bootstrap_set( name.pData, libDir.pData );
120             }
121             pLibDir = &libDir;
122         }
123     }
124     return *pLibDir;
125 }
126 
127 void raisePySystemException( const char * exceptionType, const OUString & message )
128 {
129     OStringBuffer buf;
130     buf.append( "Error during bootstrapping uno (");
131     buf.append( exceptionType );
132     buf.append( "):" );
133     buf.append( OUStringToOString( message, osl_getThreadTextEncoding() ) );
134     PyErr_SetString( PyExc_SystemError, buf.makeStringAndClear().getStr() );
135 }
136 
137 extern "C" {
138 
139 static PyObject* getComponentContext (PyObject*, PyObject*)
140 {
141     PyRef ret;
142     try
143     {
144         Reference<XComponentContext> ctx;
145 
146         // getLibDir() must be called in order to set bootstrap variables correctly !
147         OUString path( getLibDir());
148         if( Runtime::isInitialized() )
149         {
150             Runtime runtime;
151             ctx = runtime.getImpl()->cargo->xContext;
152         }
153         else
154         {
155             OUString iniFile;
156             if( !path.getLength() )
157             {
158                 PyErr_SetString(
159                     PyExc_RuntimeError, "osl_getUrlFromAddress fails, that's why I cannot find ini "
160                     "file for bootstrapping python uno bridge\n" );
161                 return NULL;
162             }
163 
164             OUStringBuffer iniFileName;
165             iniFileName.append( path );
166             iniFileName.appendAscii( "/" );
167             iniFileName.appendAscii( SAL_CONFIGFILE( "pyuno" ) );
168             iniFile = iniFileName.makeStringAndClear();
169             osl::DirectoryItem item;
170             if( osl::DirectoryItem::get( iniFile, item ) == item.E_None )
171             {
172                 // in case pyuno.ini exists, use this file for bootstrapping
173                 PyThreadDetach antiguard;
174                 ctx = cppu::defaultBootstrap_InitialComponentContext (iniFile);
175             }
176             else
177             {
178                 // defaulting to the standard bootstrapping
179                 PyThreadDetach antiguard;
180                 ctx = cppu::defaultBootstrap_InitialComponentContext ();
181             }
182 
183         }
184 
185         if( ! Runtime::isInitialized() )
186         {
187             Runtime::initialize( ctx );
188         }
189         Runtime runtime;
190         ret = runtime.any2PyObject( makeAny( ctx ) );
191     }
192     catch (com::sun::star::registry::InvalidRegistryException &e)
193     {
194         // can't use raisePyExceptionWithAny() here, because the function
195         // does any conversions, which will not work with a
196         // wrongly bootstrapped pyuno!
197         raisePySystemException( "InvalidRegistryException", e.Message );
198     }
199     catch( com::sun::star::lang::IllegalArgumentException & e)
200     {
201         raisePySystemException( "IllegalArgumentException", e.Message );
202     }
203     catch( com::sun::star::script::CannotConvertException & e)
204     {
205         raisePySystemException( "CannotConvertException", e.Message );
206     }
207     catch (com::sun::star::uno::RuntimeException & e)
208     {
209         raisePySystemException( "RuntimeException", e.Message );
210     }
211     catch (com::sun::star::uno::Exception & e)
212     {
213         raisePySystemException( "uno::Exception", e.Message );
214     }
215     return ret.getAcquired();
216 }
217 
218 PyObject * extractOneStringArg( PyObject *args, char const *funcName )
219 {
220     if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
221     {
222         OStringBuffer buf;
223         buf.append( funcName ).append( ": expecting one string argument" );
224         PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
225         return NULL;
226     }
227     PyObject *obj = PyTuple_GetItem( args, 0 );
228     if( !PyString_Check( obj ) && ! PyUnicode_Check(obj))
229     {
230         OStringBuffer buf;
231         buf.append( funcName ).append( ": expecting one string argument" );
232         PyErr_SetString( PyExc_TypeError, buf.getStr());
233         return NULL;
234     }
235     return obj;
236 }
237 
238 static PyObject *createUnoStructHelper(PyObject *, PyObject* args )
239 {
240     Any IdlStruct;
241     PyRef ret;
242 
243     try
244     {
245         Runtime runtime;
246         if( PyTuple_Size( args ) == 2 )
247         {
248             PyObject *structName = PyTuple_GetItem( args,0 );
249             PyObject *initializer = PyTuple_GetItem( args ,1 );
250 
251             if( PyString_Check( structName ) )
252             {
253                 if( PyTuple_Check( initializer ) )
254                 {
255                     OUString typeName( OUString::createFromAscii(PyString_AsString(structName)));
256                     RuntimeCargo *c = runtime.getImpl()->cargo;
257                     Reference<XIdlClass> idl_class ( c->xCoreReflection->forName (typeName),UNO_QUERY);
258                     if (idl_class.is ())
259                     {
260                         idl_class->createObject (IdlStruct);
261                         PyUNO *me = (PyUNO*)PyUNO_new_UNCHECKED( IdlStruct, c->xInvocation );
262                         PyRef returnCandidate( (PyObject*)me, SAL_NO_ACQUIRE );
263                         if( PyTuple_Size( initializer ) > 0 )
264                         {
265                             TypeDescription desc( typeName );
266                             OSL_ASSERT( desc.is() ); // could already instantiate an XInvocation2 !
267 
268                             typelib_CompoundTypeDescription *pCompType =
269                                 ( typelib_CompoundTypeDescription * ) desc.get();
270                             sal_Int32 n = fillStructWithInitializer(
271                                 me->members->xInvocation, pCompType, initializer, runtime );
272                             if( n != PyTuple_Size(initializer) )
273                             {
274                                 OUStringBuffer buf;
275                                 buf.appendAscii( "pyuno._createUnoStructHelper: wrong number of ");
276                                 buf.appendAscii( "elements in the initializer list, expected " );
277                                 buf.append( n );
278                                 buf.appendAscii( ", got " );
279                                 buf.append( (sal_Int32) PyTuple_Size(initializer) );
280                                 throw RuntimeException(
281                                     buf.makeStringAndClear(), Reference< XInterface > ());
282                             }
283                         }
284                         ret = returnCandidate;
285                     }
286                     else
287                     {
288                         OStringBuffer buf;
289                         buf.append( "UNO struct " );
290                         buf.append( PyString_AsString(structName) );
291                         buf.append( " is unkown" );
292                         PyErr_SetString (PyExc_RuntimeError, buf.getStr());
293                     }
294                 }
295                 else
296                 {
297                     PyErr_SetString(
298                         PyExc_RuntimeError,
299                         "pyuno._createUnoStructHelper: 2nd argument (initializer sequence) is no tuple" );
300                 }
301             }
302             else
303             {
304                 PyErr_SetString (PyExc_AttributeError, "createUnoStruct: first argument wasn't a string");
305             }
306         }
307         else
308         {
309             PyErr_SetString (PyExc_AttributeError, "1 Arguments: Structure Name");
310         }
311     }
312     catch( com::sun::star::uno::RuntimeException & e )
313     {
314         raisePyExceptionWithAny( makeAny( e ) );
315     }
316     catch( com::sun::star::script::CannotConvertException & e )
317     {
318         raisePyExceptionWithAny( makeAny( e ) );
319     }
320     catch( com::sun::star::uno::Exception & e )
321     {
322         raisePyExceptionWithAny( makeAny( e ) );
323     }
324     return ret.getAcquired();
325 }
326 
327 static PyObject *getTypeByName( PyObject *, PyObject *args )
328 {
329     PyObject * ret = NULL;
330 
331     try
332     {
333         char *name;
334 
335         if (PyArg_ParseTuple (args, const_cast< char * >("s"), &name))
336         {
337             OUString typeName ( OUString::createFromAscii( name ) );
338             TypeDescription typeDesc( typeName );
339             if( typeDesc.is() )
340             {
341                 Runtime runtime;
342                 ret = PyUNO_Type_new(
343                     name, (com::sun::star::uno::TypeClass)typeDesc.get()->eTypeClass, runtime );
344             }
345             else
346             {
347                 OStringBuffer buf;
348                 buf.append( "Type " ).append(name).append( " is unknown" );
349                 PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
350             }
351         }
352     }
353     catch ( RuntimeException & e )
354     {
355         raisePyExceptionWithAny( makeAny( e ) );
356     }
357     return ret;
358 }
359 
360 static PyObject *getConstantByName( PyObject *, PyObject *args )
361 {
362     PyObject *ret = 0;
363     try
364     {
365         char *name;
366 
367         if (PyArg_ParseTuple (args, const_cast< char * >("s"), &name))
368         {
369             OUString typeName ( OUString::createFromAscii( name ) );
370             Runtime runtime;
371             Any a = runtime.getImpl()->cargo->xTdMgr->getByHierarchicalName(typeName);
372             if( a.getValueType().getTypeClass() ==
373                 com::sun::star::uno::TypeClass_INTERFACE )
374             {
375                 // a idl constant cannot be an instance of an uno-object, thus
376                 // this cannot be a constant
377                 OUStringBuffer buf;
378                 buf.appendAscii( "pyuno.getConstantByName: " ).append( typeName );
379                 buf.appendAscii( "is not a constant" );
380                 throw RuntimeException(buf.makeStringAndClear(), Reference< XInterface > () );
381             }
382             PyRef constant = runtime.any2PyObject( a );
383             ret = constant.getAcquired();
384         }
385     }
386     catch( NoSuchElementException & e )
387     {
388         // to the python programmer, this is a runtime exception,
389         // do not support tweakings with the type system
390         RuntimeException runExc( e.Message, Reference< XInterface > () );
391         raisePyExceptionWithAny( makeAny( runExc ) );
392     }
393     catch( com::sun::star::script::CannotConvertException & e)
394     {
395         raisePyExceptionWithAny( makeAny( e ) );
396     }
397     catch( com::sun::star::lang::IllegalArgumentException & e)
398     {
399         raisePyExceptionWithAny( makeAny( e ) );
400     }
401     catch( RuntimeException & e )
402     {
403         raisePyExceptionWithAny( makeAny(e) );
404     }
405     return ret;
406 }
407 
408 static PyObject *checkType( PyObject *, PyObject *args )
409 {
410     if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
411     {
412         OStringBuffer buf;
413         buf.append( "pyuno.checkType : expecting one uno.Type argument" );
414         PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
415         return NULL;
416     }
417     PyObject *obj = PyTuple_GetItem( args, 0 );
418 
419     try
420     {
421         PyType2Type( obj );
422     }
423     catch( RuntimeException & e)
424     {
425         raisePyExceptionWithAny( makeAny( e ) );
426         return NULL;
427     }
428     Py_INCREF( Py_None );
429     return Py_None;
430 }
431 
432 static PyObject *checkEnum( PyObject *, PyObject *args )
433 {
434     if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
435     {
436         OStringBuffer buf;
437         buf.append( "pyuno.checkType : expecting one uno.Type argument" );
438         PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
439         return NULL;
440     }
441     PyObject *obj = PyTuple_GetItem( args, 0 );
442 
443     try
444     {
445         PyEnum2Enum( obj );
446     }
447     catch( RuntimeException & e)
448     {
449         raisePyExceptionWithAny( makeAny( e) );
450         return NULL;
451     }
452     Py_INCREF( Py_None );
453     return Py_None;
454 }
455 
456 static PyObject *getClass( PyObject *, PyObject *args )
457 {
458     PyObject *obj = extractOneStringArg( args, "pyuno.getClass");
459     if( ! obj )
460         return NULL;
461 
462     try
463     {
464         Runtime runtime;
465         PyRef ret = getClass(
466             OUString( PyString_AsString( obj), strlen(PyString_AsString(obj)),RTL_TEXTENCODING_ASCII_US),
467             runtime );
468         Py_XINCREF( ret.get() );
469         return ret.get();
470     }
471     catch( RuntimeException & e)
472     {
473         // NOOPT !!!
474         // gcc 3.2.3 crashes here in the regcomp test scenario
475         // only since migration to python 2.3.4 ???? strange thing
476         // optimization switched off for this module !
477         raisePyExceptionWithAny( makeAny(e) );
478     }
479     return NULL;
480 }
481 
482 static PyObject *isInterface( PyObject *, PyObject *args )
483 {
484 
485     if( PyTuple_Check( args ) && PyTuple_Size( args ) == 1 )
486     {
487         PyObject *obj = PyTuple_GetItem( args, 0 );
488         Runtime r;
489         return PyInt_FromLong( isInterfaceClass( r, obj ) );
490     }
491     return PyInt_FromLong( 0 );
492 }
493 
494 static PyObject * generateUuid( PyObject *, PyObject * )
495 {
496     Sequence< sal_Int8 > seq( 16 );
497     rtl_createUuid( (sal_uInt8*)seq.getArray() , 0 , sal_False );
498     PyRef ret;
499     try
500     {
501         Runtime runtime;
502         ret = runtime.any2PyObject( makeAny( seq ) );
503     }
504     catch( RuntimeException & e )
505     {
506         raisePyExceptionWithAny( makeAny(e) );
507     }
508     return ret.getAcquired();
509 }
510 
511 static PyObject *systemPathToFileUrl( PyObject *, PyObject * args )
512 {
513     PyObject *obj = extractOneStringArg( args, "pyuno.systemPathToFileUrl" );
514     if( ! obj )
515         return NULL;
516 
517     OUString sysPath = pyString2ustring( obj );
518     OUString url;
519     osl::FileBase::RC e = osl::FileBase::getFileURLFromSystemPath( sysPath, url );
520 
521     if( e != osl::FileBase::E_None )
522     {
523         OUStringBuffer buf;
524         buf.appendAscii( "Couldn't convert " );
525         buf.append( sysPath );
526         buf.appendAscii( " to a file url for reason (" );
527         buf.append( (sal_Int32) e );
528         buf.appendAscii( ")" );
529         raisePyExceptionWithAny(
530             makeAny( RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () )));
531         return NULL;
532     }
533     return ustring2PyUnicode( url ).getAcquired();
534 }
535 
536 static PyObject * fileUrlToSystemPath( PyObject *, PyObject * args )
537 {
538     PyObject *obj = extractOneStringArg( args, "pyuno.fileUrlToSystemPath" );
539     if( ! obj )
540         return NULL;
541 
542     OUString url = pyString2ustring( obj );
543     OUString sysPath;
544     osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL( url, sysPath );
545 
546     if( e != osl::FileBase::E_None )
547     {
548         OUStringBuffer buf;
549         buf.appendAscii( "Couldn't convert file url " );
550         buf.append( sysPath );
551         buf.appendAscii( " to a system path for reason (" );
552         buf.append( (sal_Int32) e );
553         buf.appendAscii( ")" );
554         raisePyExceptionWithAny(
555             makeAny( RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () )));
556         return NULL;
557     }
558     return ustring2PyUnicode( sysPath ).getAcquired();
559 }
560 
561 static PyObject * absolutize( PyObject *, PyObject * args )
562 {
563     if( PyTuple_Check( args ) && PyTuple_Size( args ) == 2 )
564     {
565         OUString ouPath = pyString2ustring( PyTuple_GetItem( args , 0 ) );
566         OUString ouRel = pyString2ustring( PyTuple_GetItem( args, 1 ) );
567         OUString ret;
568         oslFileError e = osl_getAbsoluteFileURL( ouPath.pData, ouRel.pData, &(ret.pData) );
569         if( e != osl_File_E_None )
570         {
571             OUStringBuffer buf;
572             buf.appendAscii( "Couldn't absolutize " );
573             buf.append( ouRel );
574             buf.appendAscii( " using root " );
575             buf.append( ouPath );
576             buf.appendAscii( " for reason (" );
577             buf.append( (sal_Int32) e );
578             buf.appendAscii( ")" );
579 
580             PyErr_SetString(
581                 PyExc_OSError,
582                 OUStringToOString(buf.makeStringAndClear(),osl_getThreadTextEncoding()));
583             return 0;
584         }
585         return ustring2PyUnicode( ret ).getAcquired();
586     }
587     return 0;
588 }
589 
590 static PyObject * invoke ( PyObject *, PyObject * args )
591 {
592     PyObject *ret = 0;
593     if( PyTuple_Check( args ) && PyTuple_Size( args ) == 3 )
594     {
595         PyObject *object = PyTuple_GetItem( args, 0 );
596 
597         if( PyString_Check( PyTuple_GetItem( args, 1 ) ) )
598         {
599             const char *name = PyString_AsString( PyTuple_GetItem( args, 1 ) );
600             if( PyTuple_Check( PyTuple_GetItem( args , 2 )))
601             {
602                 ret = PyUNO_invoke( object, name , PyTuple_GetItem( args, 2 ) );
603             }
604             else
605             {
606                 OStringBuffer buf;
607                 buf.append( "uno.invoke expects a tuple as 3rd argument, got " );
608                 buf.append( PyString_AsString( PyObject_Str( PyTuple_GetItem( args, 2) ) ) );
609                 PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
610             }
611         }
612         else
613         {
614             OStringBuffer buf;
615             buf.append( "uno.invoke expected a string as 2nd argument, got " );
616             buf.append( PyString_AsString( PyObject_Str( PyTuple_GetItem( args, 1) ) ) );
617             PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
618         }
619     }
620     else
621     {
622         OStringBuffer buf;
623         buf.append( "uno.invoke expects object, name, (arg1, arg2, ... )\n" );
624         PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
625     }
626     return ret;
627 }
628 
629 static PyObject *getCurrentContext( PyObject *, PyObject * )
630 {
631     PyRef ret;
632     try
633     {
634         Runtime runtime;
635         ret = runtime.any2PyObject(
636             makeAny( com::sun::star::uno::getCurrentContext() ) );
637     }
638     catch( com::sun::star::uno::Exception & e )
639     {
640         raisePyExceptionWithAny( makeAny( e ) );
641     }
642     return ret.getAcquired();
643 }
644 
645 static PyObject *setCurrentContext( PyObject *, PyObject * args )
646 {
647     PyRef ret;
648     try
649     {
650         if( PyTuple_Check( args ) && PyTuple_Size( args ) == 1 )
651         {
652 
653             Runtime runtime;
654             Any a = runtime.pyObject2Any( PyTuple_GetItem( args, 0 ) );
655 
656             Reference< com::sun::star::uno::XCurrentContext > context;
657 
658             if( (a.hasValue() && (a >>= context)) || ! a.hasValue() )
659             {
660                 ret = com::sun::star::uno::setCurrentContext( context ) ? Py_True : Py_False;
661             }
662             else
663             {
664                 OStringBuffer buf;
665                 buf.append( "uno.setCurrentContext expects an XComponentContext implementation, got " );
666                 buf.append( PyString_AsString( PyObject_Str( PyTuple_GetItem( args, 0) ) ) );
667                 PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
668             }
669         }
670         else
671         {
672             OStringBuffer buf;
673             buf.append( "uno.setCurrentContext expects exactly one argument (the current Context)\n" );
674             PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
675         }
676     }
677     catch( com::sun::star::uno::Exception & e )
678     {
679         raisePyExceptionWithAny( makeAny( e ) );
680     }
681     return ret.getAcquired();
682 }
683 
684 }
685 
686 struct PyMethodDef PyUNOModule_methods [] =
687 {
688     {const_cast< char * >("getComponentContext"), getComponentContext, 1, NULL},
689     {const_cast< char * >("_createUnoStructHelper"), createUnoStructHelper, 2, NULL},
690     {const_cast< char * >("getTypeByName"), getTypeByName, 1, NULL},
691     {const_cast< char * >("getConstantByName"), getConstantByName,1, NULL},
692     {const_cast< char * >("getClass"), getClass,1, NULL},
693     {const_cast< char * >("checkEnum"), checkEnum, 1, NULL},
694     {const_cast< char * >("checkType"), checkType, 1, NULL},
695     {const_cast< char * >("generateUuid"), generateUuid,0, NULL},
696     {const_cast< char * >("systemPathToFileUrl"),systemPathToFileUrl,1, NULL},
697     {const_cast< char * >("fileUrlToSystemPath"),fileUrlToSystemPath,1, NULL},
698     {const_cast< char * >("absolutize"),absolutize,2, NULL},
699     {const_cast< char * >("isInterface"),isInterface,1, NULL},
700     {const_cast< char * >("invoke"),invoke, 2, NULL},
701     {const_cast< char * >("setCurrentContext"),setCurrentContext,1, NULL},
702     {const_cast< char * >("getCurrentContext"),getCurrentContext,1, NULL},
703     {NULL, NULL, 0, NULL}
704 };
705 
706 }
707 
708 extern "C" PY_DLLEXPORT void initpyuno()
709 {
710     // noop when called already, otherwise needed to allow multiple threads
711     PyEval_InitThreads();
712     Py_InitModule (const_cast< char * >("pyuno"), PyUNOModule_methods);
713 }
714