1*cdf0e10cSrcweir #ifndef _PYUNO_PYUNO_HXX_ 2*cdf0e10cSrcweir #define _PYUNO_PYUNO_HXX_ 3*cdf0e10cSrcweir 4*cdf0e10cSrcweir #ifndef Py_PYTHON_H 5*cdf0e10cSrcweir #if defined _MSC_VER 6*cdf0e10cSrcweir #pragma warning(push, 1) 7*cdf0e10cSrcweir #endif 8*cdf0e10cSrcweir #ifdef _DEBUG 9*cdf0e10cSrcweir #undef _DEBUG 10*cdf0e10cSrcweir #include <Python.h> 11*cdf0e10cSrcweir #define _DEBUG 12*cdf0e10cSrcweir #else 13*cdf0e10cSrcweir #include <Python.h> 14*cdf0e10cSrcweir #endif // #ifdef _DEBUG 15*cdf0e10cSrcweir #if defined _MSC_VER 16*cdf0e10cSrcweir #pragma warning(pop) 17*cdf0e10cSrcweir #endif 18*cdf0e10cSrcweir #endif // #ifdef Py_PYTHON_H 19*cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp> 20*cdf0e10cSrcweir #include <com/sun/star/script/CannotConvertException.hpp> 21*cdf0e10cSrcweir #include <com/sun/star/lang/IllegalArgumentException.hpp> 22*cdf0e10cSrcweir 23*cdf0e10cSrcweir /** 24*cdf0e10cSrcweir External interface of the Python UNO bridge. 25*cdf0e10cSrcweir 26*cdf0e10cSrcweir This is a C++ interface, because the core UNO components 27*cdf0e10cSrcweir invocation and proxyfactory are used to implement the bridge. 28*cdf0e10cSrcweir 29*cdf0e10cSrcweir This interface is somewhat private and my change in future. 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir A scripting framework implementation may use this interface 32*cdf0e10cSrcweir to do the necessary conversions. 33*cdf0e10cSrcweir */ 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #ifdef WIN32 36*cdf0e10cSrcweir #define PY_DLLEXPORT __declspec(dllexport) 37*cdf0e10cSrcweir #else 38*cdf0e10cSrcweir #define PY_DLLEXPORT 39*cdf0e10cSrcweir #endif 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir /** function called by the python runtime to initialize the 42*cdf0e10cSrcweir pyuno module. 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir preconditions: python has been initialized before and 45*cdf0e10cSrcweir the global interpreter lock is held 46*cdf0e10cSrcweir */ 47*cdf0e10cSrcweir extern "C" PY_DLLEXPORT void SAL_CALL initpyuno(); 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir namespace pyuno 51*cdf0e10cSrcweir { 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir /** Helper class for keeping references to python objects. 54*cdf0e10cSrcweir BEWARE: Look up every python function you use to check 55*cdf0e10cSrcweir wether you get an acquired or not acquired object pointer 56*cdf0e10cSrcweir (python terminus for a not acquired object pointer 57*cdf0e10cSrcweir is 'borrowed reference'). Use in the acquired pointer cases the 58*cdf0e10cSrcweir PyRef( pointer, SAL_NO_ACQUIRE) ctor. 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir precondition: python has been initialized before and 61*cdf0e10cSrcweir the global interpreter lock is held 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir */ 64*cdf0e10cSrcweir class PyRef 65*cdf0e10cSrcweir { 66*cdf0e10cSrcweir PyObject *m; 67*cdf0e10cSrcweir public: 68*cdf0e10cSrcweir PyRef () : m(0) {} 69*cdf0e10cSrcweir PyRef( PyObject * p ) : m( p ) { Py_XINCREF( m ); } 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir PyRef( PyObject * p, __sal_NoAcquire ) : m( p ) {} 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir PyRef( const PyRef &r ) : m( r.get() ) { Py_XINCREF( m ); } 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir ~PyRef() { Py_XDECREF( m ); } 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir PyObject *get() const { return m; } 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir PyObject * getAcquired() const 80*cdf0e10cSrcweir { 81*cdf0e10cSrcweir Py_XINCREF( const_cast< PyObject*> (m) ); 82*cdf0e10cSrcweir return m; 83*cdf0e10cSrcweir } 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir PyRef & operator = ( const PyRef & r ) 86*cdf0e10cSrcweir { 87*cdf0e10cSrcweir PyObject *tmp = m; 88*cdf0e10cSrcweir m = r.getAcquired(); 89*cdf0e10cSrcweir Py_XDECREF( tmp ); 90*cdf0e10cSrcweir return *this; 91*cdf0e10cSrcweir } 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir bool operator == ( const PyRef & r ) const 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir return r.get() == m; 96*cdf0e10cSrcweir } 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir /** clears the reference without decreasing the reference count 99*cdf0e10cSrcweir only seldomly needed ! */ 100*cdf0e10cSrcweir void scratch() 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir m = 0; 103*cdf0e10cSrcweir } 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir /** clears the reference decreasing the refcount of the holded object. 106*cdf0e10cSrcweir */ 107*cdf0e10cSrcweir void clear() 108*cdf0e10cSrcweir { 109*cdf0e10cSrcweir Py_XDECREF( m ); 110*cdf0e10cSrcweir m = 0; 111*cdf0e10cSrcweir } 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir /** returns 1 when the reference points to a python object python object, 114*cdf0e10cSrcweir otherwise 0. 115*cdf0e10cSrcweir */ 116*cdf0e10cSrcweir sal_Bool is() const 117*cdf0e10cSrcweir { 118*cdf0e10cSrcweir return m != 0; 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir struct Hash 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir sal_IntPtr operator () ( const PyRef &r) const { return sal_IntPtr( r.get() ); } 124*cdf0e10cSrcweir }; 125*cdf0e10cSrcweir }; 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir struct stRuntimeImpl; 128*cdf0e10cSrcweir typedef struct stRuntimeImpl RuntimeImpl; 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir enum ConversionMode { ACCEPT_UNO_ANY, REJECT_UNO_ANY }; 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir /** The pyuno::Runtime class keeps the internal state of the python UNO bridge 134*cdf0e10cSrcweir for the currently in use python interpreter. 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir You may keep a Runtime instance, use it from a different thread, etc. But you must 137*cdf0e10cSrcweir make sure to fulfill all preconditions mentioned for the specific methods. 138*cdf0e10cSrcweir */ 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir class PY_DLLEXPORT Runtime 141*cdf0e10cSrcweir { 142*cdf0e10cSrcweir RuntimeImpl *impl; 143*cdf0e10cSrcweir public: 144*cdf0e10cSrcweir ~Runtime( ); 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir /** 147*cdf0e10cSrcweir preconditions: python has been initialized before, 148*cdf0e10cSrcweir the global interpreter lock is held and pyuno 149*cdf0e10cSrcweir has been initialized for the currently used interpreter. 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir Note: This method exists for efficiency reasons to save 152*cdf0e10cSrcweir lookup costs for any2PyObject and pyObject2Any 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir @throw RuntimeException in case the runtime has not been 155*cdf0e10cSrcweir initialized before 156*cdf0e10cSrcweir */ 157*cdf0e10cSrcweir Runtime() throw( com::sun::star::uno::RuntimeException ); 158*cdf0e10cSrcweir 159*cdf0e10cSrcweir Runtime( const Runtime & ); 160*cdf0e10cSrcweir Runtime & operator = ( const Runtime & ); 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir /** Initializes the python-UNO bridge. May be called only once per python interpreter. 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir @param ctx the component context is used to instantiate bridge services needed 165*cdf0e10cSrcweir for bridging such as invocation, typeconverter, invocationadapterfactory, etc. 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir preconditions: python has been initialized before and 168*cdf0e10cSrcweir the global interpreter lock is held and pyuno is not 169*cdf0e10cSrcweir initialized (see isInitialized() ). 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir @throw RuntimeException in case the thread is not attached or the runtime 172*cdf0e10cSrcweir has not been initialized. 173*cdf0e10cSrcweir */ 174*cdf0e10cSrcweir static void SAL_CALL initialize( 175*cdf0e10cSrcweir const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & ctx ) 176*cdf0e10cSrcweir throw ( com::sun::star::uno::RuntimeException ); 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir /** Checks, whether the uno runtime is already initialized in the current python interpreter. 180*cdf0e10cSrcweir */ 181*cdf0e10cSrcweir static bool SAL_CALL isInitialized() throw (com::sun::star::uno::RuntimeException); 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir /** disposes the UNO bridge in this interpreter. All existing stubs/proxies 185*cdf0e10cSrcweir become non-functional, using these proxies/stubs leads to runtime errors. 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir preconditions: python has been initialized before and 188*cdf0e10cSrcweir the global interpreter lock is held and pyuno was 189*cdf0e10cSrcweir initialized before for the currently in use interpreter. 190*cdf0e10cSrcweir */ 191*cdf0e10cSrcweir static void SAL_CALL finalize() throw(com::sun::star::uno::RuntimeException ); 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir /** converts something contained in an UNO Any to a Python object 194*cdf0e10cSrcweir 195*cdf0e10cSrcweir preconditions: python has been initialized before, 196*cdf0e10cSrcweir the global interpreter lock is held and pyuno::Runtime 197*cdf0e10cSrcweir has been initialized. 198*cdf0e10cSrcweir */ 199*cdf0e10cSrcweir PyRef any2PyObject (const com::sun::star::uno::Any &source ) const 200*cdf0e10cSrcweir throw ( com::sun::star::script::CannotConvertException, 201*cdf0e10cSrcweir com::sun::star::lang::IllegalArgumentException, 202*cdf0e10cSrcweir com::sun::star::uno::RuntimeException ); 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir /** converts a Python object to a UNO any 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir preconditions: python has been initialized before, 207*cdf0e10cSrcweir the global interpreter lock is held and pyuno 208*cdf0e10cSrcweir has been initialized 209*cdf0e10cSrcweir */ 210*cdf0e10cSrcweir com::sun::star::uno::Any pyObject2Any ( 211*cdf0e10cSrcweir const PyRef & source , enum ConversionMode mode = REJECT_UNO_ANY ) const 212*cdf0e10cSrcweir throw ( com::sun::star::uno::RuntimeException); 213*cdf0e10cSrcweir 214*cdf0e10cSrcweir /** extracts a proper uno exception from a given python exception 215*cdf0e10cSrcweir */ 216*cdf0e10cSrcweir com::sun::star::uno::Any extractUnoException( 217*cdf0e10cSrcweir const PyRef & excType, const PyRef & excValue, const PyRef & excTraceback) const; 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir /** Returns the internal handle. Should only be used by the module implementation 220*cdf0e10cSrcweir */ 221*cdf0e10cSrcweir RuntimeImpl *getImpl() const { return impl; } 222*cdf0e10cSrcweir }; 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir /** helper class for attaching the current thread to the python runtime. 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir Attaching is done creating a new threadstate for the given interpreter 228*cdf0e10cSrcweir and acquiring the global interpreter lock. 229*cdf0e10cSrcweir 230*cdf0e10cSrcweir Usage: 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir ... don't use python here 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir PyThreadAttach guard( PyInterpreterState_Head() ); 235*cdf0e10cSrcweir { 236*cdf0e10cSrcweir ... do whatever python code you want 237*cdf0e10cSrcweir { 238*cdf0e10cSrcweir PyThreadDetach antiguard; 239*cdf0e10cSrcweir ... don't use python here 240*cdf0e10cSrcweir } 241*cdf0e10cSrcweir ... do whatever python code you want 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir } 244*cdf0e10cSrcweir ... don't use python here 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir Note: The additional scope brackets after the PyThreadAttach are needed, 247*cdf0e10cSrcweir e.g. when you would leave them away, dtors of potential pyrefs 248*cdf0e10cSrcweir may be called after the thread has detached again. 249*cdf0e10cSrcweir */ 250*cdf0e10cSrcweir class PY_DLLEXPORT PyThreadAttach 251*cdf0e10cSrcweir { 252*cdf0e10cSrcweir PyThreadState *tstate; 253*cdf0e10cSrcweir PyThreadAttach ( const PyThreadAttach & ); // not implemented 254*cdf0e10cSrcweir PyThreadAttach & operator = ( const PyThreadAttach & ); 255*cdf0e10cSrcweir public: 256*cdf0e10cSrcweir 257*cdf0e10cSrcweir /** Creates a new python threadstate and acquires the global interpreter lock. 258*cdf0e10cSrcweir precondition: The current thread MUST NOT hold the global interpreter lock. 259*cdf0e10cSrcweir postcondition: The global interpreter lock is acquired 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir @raises com::sun::star::uno::RuntimeException 262*cdf0e10cSrcweir in case no pythread state could be created 263*cdf0e10cSrcweir */ 264*cdf0e10cSrcweir PyThreadAttach( PyInterpreterState *interp) throw ( com::sun::star::uno::RuntimeException ); 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir /** Releases the global interpreter lock and destroys the thread state. 268*cdf0e10cSrcweir */ 269*cdf0e10cSrcweir ~PyThreadAttach(); 270*cdf0e10cSrcweir }; 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir /** helper class for detaching the current thread from the python runtime 273*cdf0e10cSrcweir to do some blocking, non-python related operation. 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir @see PyThreadAttach 276*cdf0e10cSrcweir */ 277*cdf0e10cSrcweir class PY_DLLEXPORT PyThreadDetach 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir PyThreadState *tstate; 280*cdf0e10cSrcweir PyThreadDetach ( const PyThreadDetach & ); // not implemented 281*cdf0e10cSrcweir PyThreadDetach & operator = ( const PyThreadDetach & ); // not implemented 282*cdf0e10cSrcweir 283*cdf0e10cSrcweir public: 284*cdf0e10cSrcweir /** Releases the global interpreter lock. 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir precondition: The current thread MUST hold the global interpreter lock. 287*cdf0e10cSrcweir postcondition: The current thread does not hold the global interpreter lock anymore. 288*cdf0e10cSrcweir */ 289*cdf0e10cSrcweir PyThreadDetach() throw ( com::sun::star::uno::RuntimeException ); 290*cdf0e10cSrcweir /** Acquires the global interpreter lock again 291*cdf0e10cSrcweir */ 292*cdf0e10cSrcweir ~PyThreadDetach(); 293*cdf0e10cSrcweir }; 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir #endif 297