Usage of Types

From Apache OpenOffice Wiki
Jump to: navigation, search


Many UNO interface functions take interfaces as arguments. If this is the case, there are three possibilities to get an instance that supports the needed interface:

  • Ask the service manager to create a service that implements that interface.
  • Call a function on a UNO object that returns that particular interface.
  • Provide an interface implementation if a listener object is required. Refer to Automation Objects with UNO Interfaces for additional information.

If createInstance() is called on the service manager or another UNO function that returns an interface, the returned object is wrapped, so that it appears to be a COM dispatch object. When it is passed into a call to a UNO function then the original UNO object is extracted from the wrapper and the bridge makes sure that the proper interface is passed to the function. If UNO objects are used, UNO interfaces do not have to be dealt with. Ensure that the object obtained from a call to a UNO object implements the proper interface before it is passed back into another UNO call.


Automation does not know about structs as they exist in other languages, for example, in C++. Instead, it uses Automation objects that contain a set of properties similar to the fields of a C++ struct. Setting or reading a member ultimately requires a call to IDispatch::Invoke. However in languages, such as VB, VBScript, and JScript, the interface call is obscured by the programming language. Accessing the properties is as easy as with C++ structs.

  ' VB. obj is an object that implements a UNO struct
  obj.Width= 100
  obj.Height= 100

Whenever a UNO function requires a struct as an argument, the struct must be obtained from the UNO environment. It is not possible to declare a struct. For example, assume there is an office function setSize() that takes a struct of type Size. The struct is declared as follows:

  // UNO IDL
  struct Size
      long Width;
      long Height;
  // the interface function, that will be called from script
  void XShape::setSize( Size aSize)

You cannot write code similar to the following example (VBScript):

  Class Size
      Dim Width
      Dim Height
  End Class
  'obtain object that implements Xshape
  'now set the size
  call objXShape.setSize( new Size) // wrong

The service or the Bridge_GetStruct function that is called on the service manager object can be used to create the struct. The following example uses the CoreReflection service

  'VBScript in Windows Scripting Host
  Set objServiceManager= Wscript.CreateObject("")
  'Create the CoreReflection service that is later used to create structs
  Set objCoreReflection= objServiceManager.createInstance("")
  'get a type description class for Size
  Set classSize= objCoreReflection.forName("")
  'create the actual object
  Dim aSize
  classSize.createObject aSize
  'use aSize
  aSize.Width= 100
  aSize.Height= 12
  'pass the struct into the function
  objXShape.setSize aSize

The next example shows how Bridge_GetStruct is used.

  Set objServiceManager= Wscript.CreateObject("")
  Set aSize= objServiceManager.Bridge_GetStruct("")
  'use aSize
  aSize.Width= 100
  aSize.Height= 12
  objXShape.setSize aSize

The Bridge_GetStruct function is provided by the service manager object that is initially created by CreateObject (Visual Basic) or CoCreateInstance[Ex] (VC++).c

The corresponding C++ examples look complicated, but ultimately the same steps are necessary. The method forName() on the CoreReflection service is called and returns a which can be asked to create an instance using createObject():

  // create the service manager of OpenOffice
  IDispatch* pdispFactory= NULL; 
  CLSID clsFactory= {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}}; 
  hr= CoCreateInstance( clsFactory, NULL, CLSCTX_ALL, __uuidof(IDispatch), (void**)&pdispFactory); 
  // create the CoreReflection service 
  OLECHAR* funcName= L"createInstance"; 
  DISPID id; 
  pdispFactory->GetIDsOfNames( IID_NULL, &funcName, 1, LOCALE_USER_DEFAULT, &id); 
  VARIANT param1; 
  VariantInit( &param1); 
  param1.vt= VT_BSTR; 
  param1.bstrVal= SysAllocString( L""); 
  DISPPARAMS dispparams= { &param1, 0, 1, 0}; 
  VARIANT result; 
  VariantInit( &result); 
  hr= pdispFactory->Invoke( id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, 
  &dispparams, &result, NULL, 0); 
  IDispatch* pdispCoreReflection= result.pdispVal; 
  VariantClear( &result); 
  // create the struct's idl class object 
  OLECHAR* strforName= L"forName"; 
  hr= pdispCoreReflection->GetIDsOfNames( IID_NULL, &strforName, 1, LOCALE_USER_DEFAULT, &id); 
  VariantClear( &param1); 
  param1.vt= VT_BSTR; 
  param1.bstrVal= SysAllocString(L""); 
  hr= pdispCoreReflection->Invoke( id, IID_NULL, LOCALE_USER_DEFAULT, 
  DISPATCH_METHOD, &dispparams, &result, NULL, 0); 
  IDispatch* pdispClass= result.pdispVal;
  VariantClear( &result);
  // create the struct
  OLECHAR* strcreateObject= L"createObject";
  hr= pdispClass->GetIDsOfNames( IID_NULL,&strcreateObject, 1, LOCALE_USER_DEFAULT, &id)
  IDispatch* pdispPropertyValue= NULL;
  VariantClear( &param1);
  param1.vt= VT_DISPATCH | VT_BYREF;
  param1.ppdispVal= &pdispPropertyValue;
  hr= pdispClass->Invoke( id, IID_NULL, LOCALE_USER_DEFAULT, 
  DISPATCH_METHOD, &dispparams, NULL, NULL, 0);
  // do something with the struct pdispPropertyValue contained in dispparams
  // ...

The Bridge_GetStruct example.

  // objectServiceManager is the service manager of the office
  OLECHAR* strstructFunc= L"Bridge_GetStruct";
  hr= objServiceManager->GetIDsOfNames( IID_NULL, &strstructFunc, 1, LOCALE_USER_DEFAULT, &id);
  VariantClear( &param1);
  param1.vt= VT_BSTR;
  param1.bstrVal= SysAllocString(
  hr= objServiceManager->Invoke( id, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD, 
  &dispparams, &result, NULL, 0);
  IDispatch* pdispPropertyValue= result.pdispVal;
  // do something with the struct pdispPropertyValue


  // struct creation via CoreReflection
  var objServiceManager= new ActiveXObject("");
  var objCoreReflection= objServiceManager.createInstance("");
  var classSize= objCoreReflection.forName("");
  var outParam= new Array();
  classSize.createObject( outParam);
  var size= outParam[0];
  //use the struct
  // ----------------------------------------------------
  // struct creation by bridge function
  var objServiceManager= new ActiveXObject("");
  var size= objServiceManager.Bridge_GetStruct("");
Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages