xref: /trunk/main/pyuno/inc/pyuno/pyuno.hxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 #if PY_MAJOR_VERSION >= 3
80 PyMODINIT_FUNC PyInit_pyuno();
81 #else
82 extern "C" PY_DLLEXPORT void SAL_CALL initpyuno();
83 #endif
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     whether 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 seldom 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();
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 
213 
214     /** Checks, whether the uno runtime is already initialized in the current python interpreter.
215      */
216     static bool SAL_CALL isInitialized();
217 
218 
219     /** disposes the UNO bridge in this interpreter. All existing stubs/proxies
220         become non-functional, using these proxies/stubs leads to runtime errors.
221 
222         preconditions: python has been initialized before and
223         the global interpreter lock is held and pyuno was
224         initialized before for the currently in use interpreter.
225     */
226     static void SAL_CALL finalize();
227 
228     /** converts something contained in an UNO Any to a Python object
229 
230         preconditions: python has been initialized before,
231         the global interpreter lock is held and pyuno::Runtime
232         has been initialized.
233     */
234     PyRef any2PyObject (const com::sun::star::uno::Any &source ) const;
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 
245     /** extracts a proper uno exception from a given python exception
246      */
247     com::sun::star::uno::Any extractUnoException(
248         const PyRef & excType, const PyRef & excValue, const PyRef & excTraceback) const;
249 
250     /** Returns the internal handle. Should only be used by the module implementation
251      */
getImpl() const252     RuntimeImpl *getImpl() const { return impl; }
253 };
254 
255 
256 /** helper class for attaching the current thread to the python runtime.
257 
258     Attaching is done creating a new threadstate for the given interpreter
259     and acquiring the global interpreter lock.
260 
261     Usage:
262 
263     ... don't use python here
264     {
265         PyThreadAttach guard( PyInterpreterState_Head() );
266         {
267             ... do whatever python code you want
268             {
269                PyThreadDetach antiguard;
270                ... don't use python here
271             }
272             ... do whatever python code you want
273         }
274     }
275     ... don't use python here
276 
277     Note: The additional scope brackets after the PyThreadAttach are needed,
278           e.g. when you would leave them away, dtors of potential pyrefs
279           may be called after the thread has detached again.
280  */
281 class PY_DLLEXPORT PyThreadAttach
282 {
283     PyThreadState *tstate;
284     PyThreadAttach ( const PyThreadAttach & ); // not implemented
285     PyThreadAttach & operator = ( const PyThreadAttach & );
286 public:
287 
288     /** Creates a new python threadstate and acquires the global interpreter lock.
289         precondition: The current thread MUST NOT hold the global interpreter lock.
290         postcondition: The global interpreter lock is acquired
291 
292         @raises com::sun::star::uno::RuntimeException
293              in case no pythread state could be created
294      */
295     PyThreadAttach( PyInterpreterState *interp);
296 
297 
298     /** Releases the global interpreter lock and destroys the thread state.
299      */
300     ~PyThreadAttach();
301 };
302 
303 /** helper class for detaching the current thread from the python runtime
304     to do some blocking, non-python related operation.
305 
306     @see PyThreadAttach
307 */
308 class PY_DLLEXPORT PyThreadDetach
309 {
310     PyThreadState *tstate;
311     PyThreadDetach ( const PyThreadDetach & ); // not implemented
312     PyThreadDetach & operator = ( const PyThreadDetach & ); // not implemented
313 
314 public:
315     /** Releases the global interpreter lock.
316 
317        precondition: The current thread MUST hold the global interpreter lock.
318        postcondition: The current thread does not hold the global interpreter lock anymore.
319     */
320     PyThreadDetach();
321     /** Acquires the global interpreter lock again
322     */
323     ~PyThreadDetach();
324 };
325 
326 }
327 #endif
328