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