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