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