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