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