Uno/OLE

From Apache OpenOffice Wiki
< Uno
Jump to: navigation, search

Uno OLE

Modules

Specification

The UNO / OLE bridge is a means to allow UNO objects to be accessed in a COM environment, that is to say a COM client can calls an UNO server without having do deal with UNO specific details. Conversely an UNO object can use COM objects and does not have to know anything about COM.

As for COM, the OLE bridge works only for Microsoft operating systems (98/2000/XP). As the name "OLE" bridge implies the bridge deals with OLE objects and not with COM objects generally. That means that only "dispatch objects" can be mapped to UNO and UNO objects are only mapped to dispatch objects.

The bridge can be incorporated by different languages as long as the languages support OLE. First of all the system must be able to run both object models. So far the bridge has proved to work reliable with C++ and JScript. VBScript, Delphi, Visual Basic still needs some testing and as for all other eligible languages they require testing from the ground up.

UNO is available whenever the UDK is installed on a machine or indirectly when an Office is installed. As for the latter, the setup needs to be run to ensure that the initial UNO object is properly registered at the system's registry. Simply copying the executables and libraries won't do.

The bridge depends on some additional services. These are

com.sun.star.script.Invocation
com.sun.star.script.InvocationAdapterFactory
com.sun.star.script.Converter
com.sun.star.reflection.CoreReflection
com.sun.star.beans.Introspection.


Implementation


In contrast to other language bindings the OLE bridge is based on services. The following paragraphs give an overview of the functionalities which are provided by them.

com.sun.star.bridge.XBridgeSupplier2

The service is able to bridge elements of one environment to elements of another environment. This feature is provided by exposing the interface com.sun.star.bridge.XBridgeSupplier2.

com.sun.star.bridge.OleBridgeSupplierVar1

The functionality is basically the same as OleBridgeSupplier2. However, the implementation should be optimized for remote access. For example, it could try to reduce the calls into the remote process. Also it could create components on its own behalf in the remote process, if this increases performance.

The name OleBridgeSupplierVar1 is admittedly badly chosen and rather nondescript. Anyway, the "Var1" indicates that the service is a variation of the OleBridgeSupplier service. And in fact the functionality is the same but the way it is achieved is partly different. OleConverterVar1 was developed to optimize performance in a remote client server environment. A scenario could look like this:

A remote UNO object object is to be converted into an OLE object. Because the bridge can only handle UNO objects which expose XInvocation it utilizes the com.sun.star.script.Invocation service that creates an invocation object out of every UNO object or struct. Invocation has to introspect the respective object which is very expensive in terms of function calls. Now consider Invocation to reside on the client and the actual object on a remote server. Obviously there would be a great many network round trips causing a negative performance impact.

OleBridgeSupplier2 is just doing that and hence it is inappropriate for this scenario. OleBridgeSupplierVar1 on the other hand allows the remote creation of Invocation. Since Invocation and the object now reside in the same process the process of creating invocation objects is a lot more efficient.

Another issue concerns the way of how the bridge realizes the IDispatch interface for UNO wrapper objects. An UNO wrapper is an object that contains an UNO object and it implements IDispatch so that the wrapper can be used in an OLE environment. Calls on the wrapper's IDispatch are mapped to calls on the XInvocation of the wrapped object.

OLE objects are used through their IDispatch interface. A function call or accessing a property is twofold. First IDispatch::GetIDsOfNames is called which basicly takes the function or property name and returns an id (DISPID). With the id at hand the IDispatch::Invoke can be called. The Invoke implementation knows by way of the DISPID exactly what function or property it has been called for.

The OleBridgeSupplier2 UNO wrapper checks in GetIDsOfNames whether the object exists or not before it issues a DISPID. The caller knows immediately if the function or property exists. This check is not carried out by OleBridgeSupplierVar1 because it would cause at least one remote call (remember the object is remote). DISPIDs are blindly passed out whenever GetIDsOfNames is being called for a new name. If the DISPID produces an error during the Invoke call then the name is cached, so that the next time GetIDsOfNames is being called the caller receives an appropriate error code.

The OleBridgeSupplierVar1 UNO wrapper has to do some more work in IDispatch::Invoke because it has not obtained any type information yet about the meaning of the current call. The wFlags parameter of IDispatch::Invoke can e.g. consist of a combination of DISPATCH_METHOD and DISPATCH_PROPERTYPUT. In this case the wrapper tries first to call a method on the wrapped UNO object and when this fails it tries to access a property. Moreover after a call to XInvocation failed the wrapper checks whether the name is correct by calling XExactName::getExactName that is provided by the invocation object. During the Invoke call information are gathered which are cached so that whenever the same call is made again the cached information are used to fasten up the process.

com.sun.star.bridge.OleApplicationRegistration

This service registers a COM class factory when the service is being instantiated and deregisteres it when the service is being destroyed. The class factory constructs an UNO multi service factory within the OLE environment. Services created by this factory are always created in that environment. That means that someone who is using the COM class factory as starting point for an application which incorporates UNO rarely has to deal with the OLE bridge themselves.

The multi service factory which is mapped into the COM environment is the same factory which is passed into the component_getFactory function of the housing DLL. This service is deprecated

Factory com.sun.star.bridge.OleObjectFactory

The OleObjectFactory represents itself as multi service factory by exposing the XMultiServiceFactory interface. It is used to create COM objects. The COM components are specified by their programmatic identifier (ProgId). The COM objects are created in the UNO environment, meaning they are wrapped by objects which implement XInvocation and map calls to IDispatch.

To map an OLE object into the UNO environment you could create the object through any COM mechanism (e.g. CoCreateInstance) and then convert it by means of the service OleBridgeSupplier2. Actually the OleObjectFactory does not do otherwise.

Test

Misc

Personal tools