1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_PYUNO_INC_PYUNO_HXX
21 #define INCLUDED_PYUNO_INC_PYUNO_HXX
25 #endif // #ifdef Py_PYTHON_H
26 #include <com/sun/star/uno/XComponentContext.hpp>
27 #include <com/sun/star/script/CannotConvertException.hpp>
28 #include <com/sun/star/lang/IllegalArgumentException.hpp>
31 External interface of the Python UNO bridge.
33 This is a C++ interface, because the core UNO components
34 invocation and proxyfactory are used to implement the bridge.
36 This interface is somewhat private and my change in future.
38 A scripting framework implementation may use this interface
39 to do the necessary conversions.
42 #if defined LO_DLLIMPLEMENTATION_PYUNO
43 #define LO_DLLPUBLIC_PYUNO SAL_DLLPUBLIC_EXPORT
45 #define LO_DLLPUBLIC_PYUNO SAL_DLLPUBLIC_IMPORT
48 /** function called by the python runtime to initialize the
51 preconditions: python has been initialized before and
52 the global interpreter lock is held
55 extern "C" LO_DLLPUBLIC_PYUNO
56 #if PY_MAJOR_VERSION >= 3
57 PyObject
* PyInit_pyuno();
67 /** definition of a no acquire enum for ctors
72 /** Helper class for keeping references to python objects.
73 BEWARE: Look up every python function you use to check
74 whether you get an acquired or not acquired object pointer
75 (python terminus for a not acquired object pointer
76 is 'borrowed reference'). Use in the acquired pointer cases the
77 PyRef( pointer, SAL_NO_ACQUIRE) ctor.
79 precondition: python has been initialized before and
80 the global interpreter lock is held
87 PyRef () : m(nullptr) {}
88 PyRef( PyObject
* p
) : m( p
) { Py_XINCREF( m
); }
90 PyRef( PyObject
* p
, __sal_NoAcquire
) : m( p
) {}
92 PyRef( PyObject
* p
, __sal_NoAcquire
, NotNull
) : m( p
)
95 throw std::bad_alloc();
98 PyRef(const PyRef
&r
) : m(r
.get()) { Py_XINCREF(m
); }
99 PyRef(PyRef
&&r
) : m(r
.get()) { r
.scratch(); }
101 ~PyRef() { Py_XDECREF( m
); }
103 PyObject
*get() const { return m
; }
105 PyObject
* getAcquired() const
111 PyRef
& operator=(const PyRef
& r
)
119 PyRef
& operator=(PyRef
&& r
)
128 bool operator == ( const PyRef
& r
) const
133 /** clears the reference without decreasing the reference count
134 only seldom needed ! */
140 /** returns 1 when the reference points to a python object python object,
150 sal_IntPtr
operator () ( const PyRef
&r
) const { return sal_IntPtr( r
.get() ); }
154 struct stRuntimeImpl
;
155 typedef struct stRuntimeImpl RuntimeImpl
;
157 enum ConversionMode
{ ACCEPT_UNO_ANY
, REJECT_UNO_ANY
};
160 /** The pyuno::Runtime class keeps the internal state of the python UNO bridge
161 for the currently in use python interpreter.
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.
167 class LO_DLLPUBLIC_PYUNO Runtime
172 Safely unpacks a Python iterator into a sequence, then
173 stores it in an Any. Used internally by pyObject2Any
175 bool pyIterUnpack( PyObject
*const, css::uno::Any
& ) const;
180 preconditions: python has been initialized before,
181 the global interpreter lock is held and pyuno
182 has been initialized for the currently used interpreter.
184 Note: This method exists for efficiency reasons to save
185 lookup costs for any2PyObject and pyObject2Any
187 @throw RuntimeException in case the runtime has not been
192 Runtime( const Runtime
& );
193 Runtime
& operator = ( const Runtime
& );
195 /** Initializes the python-UNO bridge. May be called only once per python interpreter.
197 @param ctx the component context is used to instantiate bridge services needed
198 for bridging such as invocation, typeconverter, invocationadapterfactory, etc.
200 preconditions: python has been initialized before and
201 the global interpreter lock is held and pyuno is not
202 initialized (see isInitialized() ).
204 @throw RuntimeException in case the thread is not attached or the runtime
205 has not been initialized.
207 static void initialize(
208 const css::uno::Reference
< css::uno::XComponentContext
> & ctx
);
210 /** Checks, whether the uno runtime is already initialized in the current python interpreter.
212 @throws css::uno::RuntimeException
214 static bool isInitialized();
216 /** converts something contained in an UNO Any to a Python object
218 preconditions: python has been initialized before,
219 the global interpreter lock is held and pyuno::Runtime
220 has been initialized.
222 @throws css::script::CannotConvertException
223 @throws css::lang::IllegalArgumentException
224 @throws css::uno::RuntimeException
226 PyRef
any2PyObject (const css::uno::Any
&source
) const;
228 /** converts a Python object to a UNO any
230 preconditions: python has been initialized before,
231 the global interpreter lock is held and pyuno
234 @throws css::uno::RuntimeException
236 css::uno::Any
pyObject2Any (
237 const PyRef
& source
, enum ConversionMode mode
= REJECT_UNO_ANY
) const;
239 /** extracts a proper uno exception from a given python exception
241 css::uno::Any
extractUnoException(
242 const PyRef
& excType
, const PyRef
& excValue
, const PyRef
& excTraceback
) const;
244 /** Returns the internal handle. Should only be used by the module implementation
246 RuntimeImpl
*getImpl() const { return impl
; }
250 /** helper class for attaching the current thread to the python runtime.
252 Attaching is done creating a new threadstate for the given interpreter
253 and acquiring the global interpreter lock.
257 ... don't use python here
259 PyThreadAttach guard( PyInterpreterState_Head() );
261 ... do whatever python code you want
263 PyThreadDetach antiguard;
264 ... don't use python here
266 ... do whatever python code you want
269 ... don't use python here
271 Note: The additional scope brackets after the PyThreadAttach are needed,
272 e.g. when you would leave them away, dtors of potential pyrefs
273 may be called after the thread has detached again.
275 class LO_DLLPUBLIC_PYUNO PyThreadAttach
277 PyThreadState
*tstate
;
278 PyThreadAttach ( const PyThreadAttach
& ) = delete;
279 PyThreadAttach
& operator = ( const PyThreadAttach
& ) = delete;
282 /** Creates a new python threadstate and acquires the global interpreter lock.
283 precondition: The current thread MUST NOT hold the global interpreter lock.
284 postcondition: The global interpreter lock is acquired
286 @throws css::uno::RuntimeException
287 in case no pythread state could be created
289 PyThreadAttach( PyInterpreterState
*interp
);
292 /** Releases the global interpreter lock and destroys the thread state.
297 /** helper class for detaching the current thread from the python runtime
298 to do some blocking, non-python related operation.
302 class LO_DLLPUBLIC_PYUNO PyThreadDetach
304 PyThreadState
*tstate
;
305 PyThreadDetach ( const PyThreadDetach
& ) = delete;
306 PyThreadDetach
& operator = ( const PyThreadDetach
& ) = delete;
309 /** Releases the global interpreter lock.
311 precondition: The current thread MUST hold the global interpreter lock.
312 postcondition: The current thread does not hold the global interpreter lock anymore.
314 @throws css::uno::RuntimeException
317 /** Acquires the global interpreter lock again
325 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */