Difference between revisions of "Documentation/DevGuide/AdvUNO/Example Python Bridge PyUNO"

From Apache OpenOffice Wiki
Jump to: navigation, search
m
 
(3 intermediate revisions by 2 users not shown)
Line 6: Line 6:
 
|NextPage=Documentation/DevGuide/AdvUNO/Implementation Loader
 
|NextPage=Documentation/DevGuide/AdvUNO/Implementation Loader
 
}}
 
}}
 +
{{Documentation/DevGuideLanguages|Documentation/DevGuide/AdvUNO/{{SUBPAGENAME}}}}
 
{{DISPLAYTITLE:Example: Python Bridge PyUNO}}
 
{{DISPLAYTITLE:Example: Python Bridge PyUNO}}
 
This section provides an example of how the Python UNO bridge PyUNO bootstraps a service manager and how it makes use of the Invocation service to realize method invocation. While some parts are implementation or Python specific, the example provides a general understanding of language bindings.
 
This section provides an example of how the Python UNO bridge PyUNO bootstraps a service manager and how it makes use of the Invocation service to realize method invocation. While some parts are implementation or Python specific, the example provides a general understanding of language bindings.
Line 12: Line 13:
  
 
In ''UNO.py'', Python calls <code>PyUNO.bootstrap()</code> and receives a local component context. Note the parameter setup in that, it points to an ini file that configures the bootstrapped service manager with a type library. The file ''setup.ini'' corresponds to the ''uno.ini'' file that is used with the global service manager of the office.
 
In ''UNO.py'', Python calls <code>PyUNO.bootstrap()</code> and receives a local component context. Note the parameter setup in that, it points to an ini file that configures the bootstrapped service manager with a type library. The file ''setup.ini'' corresponds to the ''uno.ini'' file that is used with the global service manager of the office.
<source lang="python">
+
<syntaxhighlight lang="python">
 
   import PyUNO
 
   import PyUNO
 
   import os
 
   import os
Line 46: Line 47:
 
                         self.XMultiServiceFactory.createInstance ( 'com.sun.star.frame.Desktop' )
 
                         self.XMultiServiceFactory.createInstance ( 'com.sun.star.frame.Desktop' )
 
                 ...
 
                 ...
</source>
+
</syntaxhighlight>
 
Python uses function tables to map Python to C functions. ''PyUNO_module.cc'' defines a table with the mappings for the PyUNO object. As shown in the following example, <code>PyUNO.bootstrap()</code> is mapped to the C function <code>newBootstrapPyUNO()</code>:
 
Python uses function tables to map Python to C functions. ''PyUNO_module.cc'' defines a table with the mappings for the PyUNO object. As shown in the following example, <code>PyUNO.bootstrap()</code> is mapped to the C function <code>newBootstrapPyUNO()</code>:
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
   static struct PyMethodDef PyUNOModule_methods [] =
 
   static struct PyMethodDef PyUNOModule_methods [] =
 
   {
 
   {
Line 58: Line 59:
 
     {NULL, NULL}
 
     {NULL, NULL}
 
   };
 
   };
</source>
+
</syntaxhighlight>
 
The function <code>newBootstrapPyUNO()</code> calls <code>Util::bootstrap()</code> in ''PyUNO_Util.cc'' and passes the location of the ''setup.ini'' file.
 
The function <code>newBootstrapPyUNO()</code> calls <code>Util::bootstrap()</code> in ''PyUNO_Util.cc'' and passes the location of the ''setup.ini'' file.
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
   static PyObject* newBootstrapPyUNO (PyObject* self, PyObject* args)
 
   static PyObject* newBootstrapPyUNO (PyObject* self, PyObject* args)
 
   {
 
   {
Line 71: Line 72:
 
     tmp_cc = Util::bootstrap (ini_file_location);
 
     tmp_cc = Util::bootstrap (ini_file_location);
 
     ...
 
     ...
</source>
+
</syntaxhighlight>
 
<code>Util::bootstrap()</code> uses <code>defaultBootstrap_InitialComponentContext(iniFile)</code> from ''cppuhelper/bootstrap.hxx'' to create a local component context and its parameter <code>iniFile</code> points to the ''setup.ini'' file that configures the local service manager to use ''service.rdb'' and ''types.rdb'' (until {{OO1.1.0}} ''applicat.rdb''). This local component context instantiates services, such as the <code>UnoUrlResolver</code>.
 
<code>Util::bootstrap()</code> uses <code>defaultBootstrap_InitialComponentContext(iniFile)</code> from ''cppuhelper/bootstrap.hxx'' to create a local component context and its parameter <code>iniFile</code> points to the ''setup.ini'' file that configures the local service manager to use ''service.rdb'' and ''types.rdb'' (until {{OO1.1.0}} ''applicat.rdb''). This local component context instantiates services, such as the <code>UnoUrlResolver</code>.
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
   Reference<XComponentContext> bootstrap (char* ini_file_location)
 
   Reference<XComponentContext> bootstrap (char* ini_file_location)
 
   {
 
   {
Line 88: Line 89:
 
     return my_component_context;
 
     return my_component_context;
 
   }
 
   }
</source>
+
</syntaxhighlight>
 
Now <code>newBootstrapPyUNO()</code> continues to set up a UNO proxy. It creates local instances of <idl>com.sun.star.script.Invocation</idl> and <idl>com.sun.star.script.Converter</idl>, and calls <code>PyUNO_new()</code>, passing the local <code>ComponentContext</code>, a reference to the <code>XSingleServiceFactory</code> interface of <idl>com.sun.star.script.Invocation</idl> and a reference to the <code>XTypeConverter</code> interface of <idl>com.sun.star.script.Converter</idl>.
 
Now <code>newBootstrapPyUNO()</code> continues to set up a UNO proxy. It creates local instances of <idl>com.sun.star.script.Invocation</idl> and <idl>com.sun.star.script.Converter</idl>, and calls <code>PyUNO_new()</code>, passing the local <code>ComponentContext</code>, a reference to the <code>XSingleServiceFactory</code> interface of <idl>com.sun.star.script.Invocation</idl> and a reference to the <code>XTypeConverter</code> interface of <idl>com.sun.star.script.Converter</idl>.
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
   static PyObject* newBootstrapPyUNO (PyObject* self, PyObject* args)
 
   static PyObject* newBootstrapPyUNO (PyObject* self, PyObject* args)
 
   {
 
   {
Line 125: Line 126:
 
    
 
    
 
   }
 
   }
</source>
+
</syntaxhighlight>
 
<code>PyUNO_new()</code> in ''PyUNO.cc'' is the function responsible for building all Python proxies. The call to <code>PyUNO_new()</code> here in <code>newBootstrapPyUno()</code> builds the first local PyUNO proxy for the <code>ComponentContext</code> object a which has been returned by <code>Util::bootstrap()</code>.  
 
<code>PyUNO_new()</code> in ''PyUNO.cc'' is the function responsible for building all Python proxies. The call to <code>PyUNO_new()</code> here in <code>newBootstrapPyUno()</code> builds the first local PyUNO proxy for the <code>ComponentContext</code> object a which has been returned by <code>Util::bootstrap()</code>.  
  
 
For this purpose, <code>PyUNO_new()</code> uses the Invocation service to retrieve an XInvocation2 interface to the <code>ComponentContext</code> service passed in the parameter a:
 
For this purpose, <code>PyUNO_new()</code> uses the Invocation service to retrieve an XInvocation2 interface to the <code>ComponentContext</code> service passed in the parameter a:
<source lang="cpp">
+
<syntaxhighlight lang="cpp">
 
   // PyUNO_new
 
   // PyUNO_new
 
   //
 
   //
Line 155: Line 156:
 
     Reference<XInvocation2 > tmp_invocation (tmp_interface, UNO_QUERY);
 
     Reference<XInvocation2 > tmp_invocation (tmp_interface, UNO_QUERY);
 
     ...
 
     ...
</source>
+
</syntaxhighlight>
 
The Python proxy invokes methods, and creates and converts UNO types. This Python specific and involves the implementation of several functions according to the Python API.
 
The Python proxy invokes methods, and creates and converts UNO types. This Python specific and involves the implementation of several functions according to the Python API.
  
Line 161: Line 162:
  
 
{{PDL1}}
 
{{PDL1}}
[[Category: Advanced UNO]]
+
 
 +
[[Category:Documentation/Developer's Guide/Advanced UNO]]

Latest revision as of 17:20, 2 January 2021



This section provides an example of how the Python UNO bridge PyUNO bootstraps a service manager and how it makes use of the Invocation service to realize method invocation. While some parts are implementation or Python specific, the example provides a general understanding of language bindings.

The Python bridge PyUNO uses the cppu helper library to bootstrap a local service manager that is asked for a UnoUrlResolver service in Python.

In UNO.py, Python calls PyUNO.bootstrap() and receives a local component context. Note the parameter setup in that, it points to an ini file that configures the bootstrapped service manager with a type library. The file setup.ini corresponds to the uno.ini file that is used with the global service manager of the office.

  import PyUNO
  import os
 
  setup_ini = 'file:///%s/setup.ini' % os.getenv ('PWD') 
 
  class UNO:
 
      def __init__ ( self, connection='socket,host=localhost,port=2083;urp', setup=setup_ini ):
                """ do the bootstrap 
 
                    connection can be one or more of the following:
 
                    socket,
                    host = localhost | <hostname> | <ip-addr>,
                    port = <port>,
                    service = soffice,
                    user = <username>,
                    password = <password>
                    ;urp
 
                """
 
                self.XComponentContext = PyUNO.bootstrap ( setup )
                self.XUnoUrlResolver, o = \
                        self.XComponentContext.ServiceManager.createInstanceWithContext (
                                'com.sun.star.bridge.UnoUrlResolver', self.XComponentContext )
                self.XNamingService, o = self.XUnoUrlResolver.resolve (
                        'uno:%s;StarOffice.NamingService' % connection )
                self.XMultiServiceFactory, o = self.XNamingService.getRegisteredObject (
                        'StarOffice.ServiceManager')
                self.XComponentLoader, o = \
                        self.XMultiServiceFactory.createInstance ( 'com.sun.star.frame.Desktop' )
                ...

Python uses function tables to map Python to C functions. PyUNO_module.cc defines a table with the mappings for the PyUNO object. As shown in the following example, PyUNO.bootstrap() is mapped to the C function newBootstrapPyUNO():

  static struct PyMethodDef PyUNOModule_methods [] =
  {
    {"bootstrapPyUNO", bootstrapPyUNO, 1},
    {"bootstrap ", newBootstrapPyUNO , 1}, 
    {"createIdlStruct", createIdlStruct, 1},
    {"true", createTrueBool, 1},
    {"false", createFalseBool, 1},
    {NULL, NULL}
  };

The function newBootstrapPyUNO() calls Util::bootstrap() in PyUNO_Util.cc and passes the location of the setup.ini file.

  static PyObject* newBootstrapPyUNO (PyObject* self, PyObject* args)
  {
    char* ini_file_location;
    Reference<XComponentContext> tmp_cc;
    Any a;
 
    if (!PyArg_ParseTuple (args, "s", &ini_file_location))
      return NULL;
    tmp_cc = Util::bootstrap (ini_file_location);
    ...

Util::bootstrap() uses defaultBootstrap_InitialComponentContext(iniFile) from cppuhelper/bootstrap.hxx to create a local component context and its parameter iniFile points to the setup.ini file that configures the local service manager to use service.rdb and types.rdb (until 1.1.0 applicat.rdb). This local component context instantiates services, such as the UnoUrlResolver.

  Reference<XComponentContext> bootstrap (char* ini_file_location)
  {
    Reference<XComponentContext> my_component_context;
    try
      {
        my_component_context = defaultBootstrap_InitialComponentContext (
                 OUString::createFromAscii (ini_file_location ));
      }
    catch (com::sun::star::uno::Exception e)
      {
        printf (OUStringToOString (e.Message, osl_getThreadTextEncoding ()).getStr ());
      }
    return my_component_context;
  }

Now newBootstrapPyUNO() continues to set up a UNO proxy. It creates local instances of com.sun.star.script.Invocation and com.sun.star.script.Converter, and calls PyUNO_new(), passing the local ComponentContext, a reference to the XSingleServiceFactory interface of com.sun.star.script.Invocation and a reference to the XTypeConverter interface of com.sun.star.script.Converter.

  static PyObject* newBootstrapPyUNO (PyObject* self, PyObject* args)
  {
    char* ini_file_location;
    Reference<XComponentContext> tmp_cc;
    Any a;
 
    if (!PyArg_ParseTuple (args, "s", &ini_file_location))
      return NULL;
    tmp_cc = Util::bootstrap (ini_file_location) ;
    Reference<XMultiServiceFactory> tmp_msf (tmp_cc->getServiceManager (), UNO_QUERY);
    if (!tmp_msf.is ())
      {
        PyErr_SetString (PyExc_RuntimeError, "Couldn't bootstrap from inifile");
        return NULL;
      }
    Reference<XSingleServiceFactory> tmp_ssf (tmp_msf->createInstance (
        OUString (RTL_CONSTASCII_USTRINGPARAM ("com.sun.star.script.Invocation "))), UNO_QUERY);
    Reference<XTypeConverter> tmp_tc (tmp_msf->createInstance (
        OUString (RTL_CONSTASCII_USTRINGPARAM ("com.sun.star.script.Converter "))), UNO_QUERY);
    if (!tmp_tc.is ())
      {
        PyErr_SetString (PyExc_RuntimeError, "Couldn't create XTypeConverter");
        return NULL;
      }
    if (!tmp_ssf.is ())
      {
        PyErr_SetString (PyExc_RuntimeError, "Couldn't create XInvocation");
        return NULL;
      }
    a <<= tmp_cc;
 
    return PyUNO_new (a, tmp_ssf, tmp_tc) ;
 
  }

PyUNO_new() in PyUNO.cc is the function responsible for building all Python proxies. The call to PyUNO_new() here in newBootstrapPyUno() builds the first local PyUNO proxy for the ComponentContext object a which has been returned by Util::bootstrap().

For this purpose, PyUNO_new() uses the Invocation service to retrieve an XInvocation2 interface to the ComponentContext service passed in the parameter a:

  // PyUNO_new
  //
  // creates Python object proxies for the given target UNO interfaces
  // targetInterface given UNO interface
  // ssf                     XSingleServiceFactory interface of com.sun.star.script.Invocation service
  // tc                      XTypeConverter interface of com.sun.star.script.Converter service
 
  PyObject* PyUNO_new (Any targetInterface, 
                    Reference<XSingleServiceFactory> ssf, 
                    Reference<XTypeConverter> tc)
    ...
    Sequence<Any> arguments (1);
    Reference<XInterface> tmp_interface;
    ...
    // put the target object into a sequence of Any for the call to 
    // ssf->createInstanceWithArguments()
    // ssf is the XSingleServiceFactory interface of the com.sun.star.script.Invocation service
    arguments[0] <<= targetInterface;
 
    // obtain com.sun.star.script.XInvocation2 for target object from Invocation
    // let Invocation create an XInvocation object for the Any in arguments
    tmp_interface = ssf->createInstanceWithArguments (arguments);
    // query XInvocation2 interface
    Reference<XInvocation2 > tmp_invocation (tmp_interface, UNO_QUERY);
    ...

The Python proxy invokes methods, and creates and converts UNO types. This Python specific and involves the implementation of several functions according to the Python API.

Finally __init__() in UNO.py in the above example uses the PyUNO object to obtain a local UnoUrlResolver that retrieves the initial object from the office.

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages