xref: /trunk/main/pyuno/inc/pyuno/pyuno.hxx (revision db6edb48b9383861b7def4c5be182fa9f3dd1475)
1*db6edb48SAndrew Rist /**************************************************************
2*db6edb48SAndrew Rist  *
3*db6edb48SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*db6edb48SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*db6edb48SAndrew Rist  * distributed with this work for additional information
6*db6edb48SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*db6edb48SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*db6edb48SAndrew Rist  * "License"); you may not use this file except in compliance
9*db6edb48SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*db6edb48SAndrew Rist  *
11*db6edb48SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*db6edb48SAndrew Rist  *
13*db6edb48SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*db6edb48SAndrew Rist  * software distributed under the License is distributed on an
15*db6edb48SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*db6edb48SAndrew Rist  * KIND, either express or implied.  See the License for the
17*db6edb48SAndrew Rist  * specific language governing permissions and limitations
18*db6edb48SAndrew Rist  * under the License.
19*db6edb48SAndrew Rist  *
20*db6edb48SAndrew Rist  *************************************************************/
21*db6edb48SAndrew Rist 
22cdf0e10cSrcweir #ifndef _PYUNO_PYUNO_HXX_
23cdf0e10cSrcweir #define _PYUNO_PYUNO_HXX_
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #ifndef Py_PYTHON_H
26cdf0e10cSrcweir #if defined _MSC_VER
27cdf0e10cSrcweir #pragma warning(push, 1)
28cdf0e10cSrcweir #endif
29cdf0e10cSrcweir #ifdef _DEBUG
30cdf0e10cSrcweir #undef _DEBUG
31cdf0e10cSrcweir #include <Python.h>
32cdf0e10cSrcweir #define _DEBUG
33cdf0e10cSrcweir #else
34cdf0e10cSrcweir #include <Python.h>
35cdf0e10cSrcweir #endif // #ifdef _DEBUG
36cdf0e10cSrcweir #if defined _MSC_VER
37cdf0e10cSrcweir #pragma warning(pop)
38cdf0e10cSrcweir #endif
39cdf0e10cSrcweir #endif // #ifdef Py_PYTHON_H
40cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp>
41cdf0e10cSrcweir #include <com/sun/star/script/CannotConvertException.hpp>
42cdf0e10cSrcweir #include <com/sun/star/lang/IllegalArgumentException.hpp>
43cdf0e10cSrcweir 
44cdf0e10cSrcweir /**
45cdf0e10cSrcweir    External interface of the Python UNO bridge.
46cdf0e10cSrcweir 
47cdf0e10cSrcweir    This is a C++ interface, because the core UNO components
48cdf0e10cSrcweir    invocation and proxyfactory are used to implement the bridge.
49cdf0e10cSrcweir 
50cdf0e10cSrcweir    This interface is somewhat private and my change in future.
51cdf0e10cSrcweir 
52cdf0e10cSrcweir    A scripting framework implementation may use this interface
53cdf0e10cSrcweir    to do the necessary conversions.
54cdf0e10cSrcweir */
55cdf0e10cSrcweir 
56cdf0e10cSrcweir #ifdef WIN32
57cdf0e10cSrcweir #define PY_DLLEXPORT __declspec(dllexport)
58cdf0e10cSrcweir #else
59cdf0e10cSrcweir #define PY_DLLEXPORT
60cdf0e10cSrcweir #endif
61cdf0e10cSrcweir 
62cdf0e10cSrcweir /** function called by the python runtime to initialize the
63cdf0e10cSrcweir     pyuno module.
64cdf0e10cSrcweir 
65cdf0e10cSrcweir     preconditions: python has been initialized before and
66cdf0e10cSrcweir                    the global interpreter lock is held
67cdf0e10cSrcweir */
68cdf0e10cSrcweir extern "C" PY_DLLEXPORT void SAL_CALL initpyuno();
69cdf0e10cSrcweir 
70cdf0e10cSrcweir 
71cdf0e10cSrcweir namespace pyuno
72cdf0e10cSrcweir {
73cdf0e10cSrcweir 
74cdf0e10cSrcweir /** Helper class for keeping references to python objects.
75cdf0e10cSrcweir     BEWARE: Look up every python function you use to check
76cdf0e10cSrcweir     wether you get an acquired or not acquired object pointer
77cdf0e10cSrcweir     (python terminus for a not acquired object pointer
78cdf0e10cSrcweir     is 'borrowed reference'). Use in the acquired pointer cases the
79cdf0e10cSrcweir     PyRef( pointer, SAL_NO_ACQUIRE) ctor.
80cdf0e10cSrcweir 
81cdf0e10cSrcweir     precondition: python has been initialized before and
82cdf0e10cSrcweir     the global interpreter lock is held
83cdf0e10cSrcweir 
84cdf0e10cSrcweir */
85cdf0e10cSrcweir class PyRef
86cdf0e10cSrcweir {
87cdf0e10cSrcweir     PyObject *m;
88cdf0e10cSrcweir public:
89cdf0e10cSrcweir     PyRef () : m(0) {}
90cdf0e10cSrcweir     PyRef( PyObject * p ) : m( p ) { Py_XINCREF( m ); }
91cdf0e10cSrcweir 
92cdf0e10cSrcweir     PyRef( PyObject * p, __sal_NoAcquire ) : m( p ) {}
93cdf0e10cSrcweir 
94cdf0e10cSrcweir     PyRef( const PyRef &r ) : m( r.get() ) { Py_XINCREF( m ); }
95cdf0e10cSrcweir 
96cdf0e10cSrcweir     ~PyRef() { Py_XDECREF( m ); }
97cdf0e10cSrcweir 
98cdf0e10cSrcweir     PyObject *get() const { return m; }
99cdf0e10cSrcweir 
100cdf0e10cSrcweir     PyObject * getAcquired() const
101cdf0e10cSrcweir     {
102cdf0e10cSrcweir         Py_XINCREF( const_cast< PyObject*> (m) );
103cdf0e10cSrcweir         return m;
104cdf0e10cSrcweir     }
105cdf0e10cSrcweir 
106cdf0e10cSrcweir     PyRef & operator = (  const PyRef & r )
107cdf0e10cSrcweir     {
108cdf0e10cSrcweir         PyObject *tmp = m;
109cdf0e10cSrcweir         m = r.getAcquired();
110cdf0e10cSrcweir         Py_XDECREF( tmp );
111cdf0e10cSrcweir         return *this;
112cdf0e10cSrcweir     }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir     bool operator == (  const PyRef & r ) const
115cdf0e10cSrcweir     {
116cdf0e10cSrcweir         return r.get() == m;
117cdf0e10cSrcweir     }
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     /** clears the reference without decreasing the reference count
120cdf0e10cSrcweir         only seldomly needed ! */
121cdf0e10cSrcweir     void scratch()
122cdf0e10cSrcweir     {
123cdf0e10cSrcweir         m = 0;
124cdf0e10cSrcweir     }
125cdf0e10cSrcweir 
126cdf0e10cSrcweir     /** clears the reference decreasing the refcount of the holded object.
127cdf0e10cSrcweir      */
128cdf0e10cSrcweir     void clear()
129cdf0e10cSrcweir     {
130cdf0e10cSrcweir         Py_XDECREF( m );
131cdf0e10cSrcweir         m = 0;
132cdf0e10cSrcweir     }
133cdf0e10cSrcweir 
134cdf0e10cSrcweir     /** returns 1 when the reference points to a python object python object,
135cdf0e10cSrcweir         otherwise 0.
136cdf0e10cSrcweir     */
137cdf0e10cSrcweir     sal_Bool is() const
138cdf0e10cSrcweir     {
139cdf0e10cSrcweir         return m != 0;
140cdf0e10cSrcweir     }
141cdf0e10cSrcweir 
142cdf0e10cSrcweir     struct Hash
143cdf0e10cSrcweir     {
144cdf0e10cSrcweir         sal_IntPtr operator () ( const PyRef &r) const { return sal_IntPtr( r.get() ); }
145cdf0e10cSrcweir     };
146cdf0e10cSrcweir };
147cdf0e10cSrcweir 
148cdf0e10cSrcweir struct stRuntimeImpl;
149cdf0e10cSrcweir typedef struct stRuntimeImpl RuntimeImpl;
150cdf0e10cSrcweir 
151cdf0e10cSrcweir enum ConversionMode { ACCEPT_UNO_ANY, REJECT_UNO_ANY };
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 
154cdf0e10cSrcweir /** The pyuno::Runtime class keeps the internal state of the python UNO bridge
155cdf0e10cSrcweir     for the currently in use python interpreter.
156cdf0e10cSrcweir 
157cdf0e10cSrcweir     You may keep a Runtime instance, use it from a different thread, etc. But you must
158cdf0e10cSrcweir     make sure to fulfill all preconditions mentioned for the specific methods.
159cdf0e10cSrcweir */
160cdf0e10cSrcweir 
161cdf0e10cSrcweir class PY_DLLEXPORT Runtime
162cdf0e10cSrcweir {
163cdf0e10cSrcweir     RuntimeImpl *impl;
164cdf0e10cSrcweir public:
165cdf0e10cSrcweir     ~Runtime( );
166cdf0e10cSrcweir 
167cdf0e10cSrcweir     /**
168cdf0e10cSrcweir         preconditions: python has been initialized before,
169cdf0e10cSrcweir         the global interpreter lock is held and pyuno
170cdf0e10cSrcweir         has been initialized for the currently used interpreter.
171cdf0e10cSrcweir 
172cdf0e10cSrcweir         Note: This method exists for efficiency reasons to save
173cdf0e10cSrcweir         lookup costs for any2PyObject and pyObject2Any
174cdf0e10cSrcweir 
175cdf0e10cSrcweir         @throw RuntimeException in case the runtime has not been
176cdf0e10cSrcweir                initialized before
177cdf0e10cSrcweir      */
178cdf0e10cSrcweir     Runtime() throw( com::sun::star::uno::RuntimeException );
179cdf0e10cSrcweir 
180cdf0e10cSrcweir     Runtime( const Runtime & );
181cdf0e10cSrcweir     Runtime & operator = ( const Runtime & );
182cdf0e10cSrcweir 
183cdf0e10cSrcweir     /** Initializes the python-UNO bridge. May be called only once per python interpreter.
184cdf0e10cSrcweir 
185cdf0e10cSrcweir         @param ctx the component context is used to instantiate bridge services needed
186cdf0e10cSrcweir         for bridging such as invocation, typeconverter, invocationadapterfactory, etc.
187cdf0e10cSrcweir 
188cdf0e10cSrcweir         preconditions: python has been initialized before and
189cdf0e10cSrcweir         the global interpreter lock is held and pyuno is not
190cdf0e10cSrcweir         initialized (see isInitialized() ).
191cdf0e10cSrcweir 
192cdf0e10cSrcweir         @throw RuntimeException in case the thread is not attached or the runtime
193cdf0e10cSrcweir                                 has not been initialized.
194cdf0e10cSrcweir     */
195cdf0e10cSrcweir     static void SAL_CALL initialize(
196cdf0e10cSrcweir         const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & ctx )
197cdf0e10cSrcweir         throw ( com::sun::star::uno::RuntimeException );
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 
200cdf0e10cSrcweir     /** Checks, whether the uno runtime is already initialized in the current python interpreter.
201cdf0e10cSrcweir      */
202cdf0e10cSrcweir     static bool SAL_CALL isInitialized() throw (com::sun::star::uno::RuntimeException);
203cdf0e10cSrcweir 
204cdf0e10cSrcweir 
205cdf0e10cSrcweir     /** disposes the UNO bridge in this interpreter. All existing stubs/proxies
206cdf0e10cSrcweir         become non-functional, using these proxies/stubs leads to runtime errors.
207cdf0e10cSrcweir 
208cdf0e10cSrcweir         preconditions: python has been initialized before and
209cdf0e10cSrcweir         the global interpreter lock is held and pyuno was
210cdf0e10cSrcweir         initialized before for the currently in use interpreter.
211cdf0e10cSrcweir     */
212cdf0e10cSrcweir     static void SAL_CALL finalize() throw(com::sun::star::uno::RuntimeException );
213cdf0e10cSrcweir 
214cdf0e10cSrcweir     /** converts something contained in an UNO Any to a Python object
215cdf0e10cSrcweir 
216cdf0e10cSrcweir         preconditions: python has been initialized before,
217cdf0e10cSrcweir         the global interpreter lock is held and pyuno::Runtime
218cdf0e10cSrcweir         has been initialized.
219cdf0e10cSrcweir     */
220cdf0e10cSrcweir     PyRef any2PyObject (const com::sun::star::uno::Any &source ) const
221cdf0e10cSrcweir         throw ( com::sun::star::script::CannotConvertException,
222cdf0e10cSrcweir                 com::sun::star::lang::IllegalArgumentException,
223cdf0e10cSrcweir                 com::sun::star::uno::RuntimeException );
224cdf0e10cSrcweir 
225cdf0e10cSrcweir     /** converts a Python object to a UNO any
226cdf0e10cSrcweir 
227cdf0e10cSrcweir         preconditions: python has been initialized before,
228cdf0e10cSrcweir         the global interpreter lock is held and pyuno
229cdf0e10cSrcweir         has been initialized
230cdf0e10cSrcweir     */
231cdf0e10cSrcweir     com::sun::star::uno::Any pyObject2Any (
232cdf0e10cSrcweir         const PyRef & source , enum ConversionMode mode = REJECT_UNO_ANY ) const
233cdf0e10cSrcweir         throw ( com::sun::star::uno::RuntimeException);
234cdf0e10cSrcweir 
235cdf0e10cSrcweir     /** extracts a proper uno exception from a given python exception
236cdf0e10cSrcweir      */
237cdf0e10cSrcweir     com::sun::star::uno::Any extractUnoException(
238cdf0e10cSrcweir         const PyRef & excType, const PyRef & excValue, const PyRef & excTraceback) const;
239cdf0e10cSrcweir 
240cdf0e10cSrcweir     /** Returns the internal handle. Should only be used by the module implementation
241cdf0e10cSrcweir      */
242cdf0e10cSrcweir     RuntimeImpl *getImpl() const { return impl; }
243cdf0e10cSrcweir };
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 
246cdf0e10cSrcweir /** helper class for attaching the current thread to the python runtime.
247cdf0e10cSrcweir 
248cdf0e10cSrcweir     Attaching is done creating a new threadstate for the given interpreter
249cdf0e10cSrcweir     and acquiring the global interpreter lock.
250cdf0e10cSrcweir 
251cdf0e10cSrcweir     Usage:
252cdf0e10cSrcweir 
253cdf0e10cSrcweir     ... don't use python here
254cdf0e10cSrcweir     {
255cdf0e10cSrcweir         PyThreadAttach guard( PyInterpreterState_Head() );
256cdf0e10cSrcweir         {
257cdf0e10cSrcweir             ... do whatever python code you want
258cdf0e10cSrcweir             {
259cdf0e10cSrcweir                PyThreadDetach antiguard;
260cdf0e10cSrcweir                ... don't use python here
261cdf0e10cSrcweir             }
262cdf0e10cSrcweir             ... do whatever python code you want
263cdf0e10cSrcweir         }
264cdf0e10cSrcweir     }
265cdf0e10cSrcweir     ... don't use python here
266cdf0e10cSrcweir 
267cdf0e10cSrcweir     Note: The additional scope brackets after the PyThreadAttach are needed,
268cdf0e10cSrcweir           e.g. when you would leave them away, dtors of potential pyrefs
269cdf0e10cSrcweir           may be called after the thread has detached again.
270cdf0e10cSrcweir  */
271cdf0e10cSrcweir class PY_DLLEXPORT PyThreadAttach
272cdf0e10cSrcweir {
273cdf0e10cSrcweir     PyThreadState *tstate;
274cdf0e10cSrcweir     PyThreadAttach ( const PyThreadAttach & ); // not implemented
275cdf0e10cSrcweir     PyThreadAttach & operator = ( const PyThreadAttach & );
276cdf0e10cSrcweir public:
277cdf0e10cSrcweir 
278cdf0e10cSrcweir     /** Creates a new python threadstate and acquires the global interpreter lock.
279cdf0e10cSrcweir         precondition: The current thread MUST NOT hold the global interpreter lock.
280cdf0e10cSrcweir         postcondition: The global interpreter lock is acquired
281cdf0e10cSrcweir 
282cdf0e10cSrcweir         @raises com::sun::star::uno::RuntimeException
283cdf0e10cSrcweir              in case no pythread state could be created
284cdf0e10cSrcweir      */
285cdf0e10cSrcweir     PyThreadAttach( PyInterpreterState *interp) throw ( com::sun::star::uno::RuntimeException );
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 
288cdf0e10cSrcweir     /** Releases the global interpreter lock and destroys the thread state.
289cdf0e10cSrcweir      */
290cdf0e10cSrcweir     ~PyThreadAttach();
291cdf0e10cSrcweir };
292cdf0e10cSrcweir 
293cdf0e10cSrcweir /** helper class for detaching the current thread from the python runtime
294cdf0e10cSrcweir     to do some blocking, non-python related operation.
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     @see PyThreadAttach
297cdf0e10cSrcweir */
298cdf0e10cSrcweir class PY_DLLEXPORT PyThreadDetach
299cdf0e10cSrcweir {
300cdf0e10cSrcweir     PyThreadState *tstate;
301cdf0e10cSrcweir     PyThreadDetach ( const PyThreadDetach & ); // not implemented
302cdf0e10cSrcweir     PyThreadDetach & operator = ( const PyThreadDetach & ); // not implemented
303cdf0e10cSrcweir 
304cdf0e10cSrcweir public:
305cdf0e10cSrcweir     /** Releases the global interpreter lock.
306cdf0e10cSrcweir 
307cdf0e10cSrcweir        precondition: The current thread MUST hold the global interpreter lock.
308cdf0e10cSrcweir        postcondition: The current thread does not hold the global interpreter lock anymore.
309cdf0e10cSrcweir     */
310cdf0e10cSrcweir     PyThreadDetach() throw ( com::sun::star::uno::RuntimeException );
311cdf0e10cSrcweir     /** Acquires the global interpreter lock again
312cdf0e10cSrcweir     */
313cdf0e10cSrcweir     ~PyThreadDetach();
314cdf0e10cSrcweir };
315cdf0e10cSrcweir 
316cdf0e10cSrcweir }
317cdf0e10cSrcweir #endif
318