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