xref: /aoo41x/main/pyuno/inc/pyuno/pyuno.hxx (revision db6edb48)
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