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