Type Mappings

From Apache OpenOffice Wiki
< Documentation‎ | DevGuide
Revision as of 13:04, 23 December 2020 by DiGro (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Mapping of Simple Types

The following table shows the mapping of simple UNO types to the corresponding C++ types.

void void
boolean sal_Bool
byte sal_Int8
short sal_Int16
unsigned short sal_uInt16
long sal_Int32
unsigned long sal_uInt32
hyper sal_Int64
unsigned hyper sal_uInt64
float float
double double
char sal_Unicode
string rtl::OUString
type com::sun::star::uno::Type
any com::sun::star::uno::Any

For historic reasons, the UNO type boolean is mapped to some C++ type sal_Bool, which has two distinct values sal_False and sal_True, and which need not be the C++ bool type. The mapping between the values of UNO boolean and sal_False and sal_True is straightforward, but it is an error to use any potential value of sal_Bool that is distinct from both sal_False and sal_True.

The UNO integer types are mapped to C++ integer types with ranges that are guaranteed to be at least as large as the ranges of the corresponding UNO types. However, the ranges of the C++ types might be larger, in which case it would be an error to use values outside of the range of the corresponding UNO types within the context of UNO. Currently, it would not be possible to create C++ language bindings for C++ environments that offer no suitable integral types that meet the minimal range guarantees.

The UNO floating point types float and double are mapped to C++ floating point types float and double, which must be capable of representing at least all the values of the corresponding UNO types. However, the C++ types might be capable of representing more values, for which it is implementation-defined how they are handled in the context of UNO. Currently, it would not be possible to create C++ language bindings for C++ environments that offer no suitable float and double types.

The UNO char type is mapped to the integral C++ type sal_Unicode, which is guaranteed to at least encompass the range from 0 to 65535. Values of UNO char are mapped to values of sal_Unicode in the obvious manner. If the range of sal_Unicode is larger, it is an error to use values outside of that range.

For the C++ typedef types sal_Bool, sal_Int8, sal_Int16, sal_Int32, sal_Int64, and sal_Unicode, it is guaranteed that no two of them are synonyms for the same fundamental C++ type. This guarantee does not extend to the three types sal_uInt8, sal_uInt16, and sal_uInt32, however.

Mapping of String

The mapping between the UNO string type and rtl::OUString is straightforward, except for two details:

  • The length of a string that can be represented by an rtl::OUString object is limited. It is an error to use a longer UNO string value in the context of the C++ language binding.
  • An object of type rtl::OUString can represent an arbitrary sequence of UTF-16 code units, whereas a value of the UNO string type is an arbitrary sequence of Unicode scalar values. This only matters in so far as some individual UTF-16 code units (namely the individual high- and low-surrogate code points in the range D800-DFFF) have no corresponding Unicode scalar values, and are thus forbidden in the context of UNO. For example, the C++ string
  static sal_Unicode const chars[] = { 0xD800 };
  rtl::OUString(chars, 1);

is illegal in this context, while the string

  static sal_Unicode const chars[] = { 0xD800, 0xDC00 };
  rtl::OUString(chars, 2);

would be legal. See www.unicode.org for more information on the details of Unicode.

Mapping of Type

The UNO type type is mapped to com::sun::star::uno::Type. It holds the name of a type and the com.sun.star.uno.TypeClass. The type allows you to obtain a com::sun::star::uno::TypeDescription that contains all the information defined in the IDL. For a given UNO type, a corresponding com::sun::star::Type instance can be obtained through the cppu::UnoType class template:

 // Get the UNO type long:
 com::sun::star::uno::Type longType = cppu::UnoType< sal_Int32 >::get();
 // Get the UNO type char:
 com::sun::star::uno::Type charTpye = cppu::UnoType< cppu::UnoCharType >::get();
 // Get the UNO type string:
 com::sun::star::uno::Type stringType = cppu::UnoType< rtl::OUString >::get();
 // Get the UNO interface type com.sun.star.container.XEnumeration:
 com::sun::star::uno::Type enumerationType =
     cppu::UnoType< com::sun::star::container::XEnumeration >::get();

Some C++ types that represent UNO types cannot be used as C++ template arguments, or ambiguously represent more than one UNO type, so there are special C++ types cppu::UnoVoidType, cppu::UnoUnsignedShortType, cppu::UnoCharType, and cppu::UnoSequenceType that can be used as arguments for cppu::UnoType in those cases.

The overloaded getCppuType function was an older mechanism to obtain com::sun::star::uno::Type instances. It is deprecated now (certain uses of getCppuType in template code would not work as intended), and cppu::UnoType should be used instead.

Mapping of Any

The IDL any is mapped to com::sun::star::uno::Any. It holds an instance of an arbitrary UNO type. Only UNO types can be stored within the any, because the data from the type library are required for any handling.

A default constructed Any contains the void type and no value. You can assign a value to the Any using the operator <<= and retrieve a value using the operator >>=.

 // default construct an any
 Any any;
 sal_Int32 n = 3;
 // Store the value into the any
 any <<= n;
 // extract the value again
 sal_Int32 n2;
 any >>= n2;
 assert( n2 == n );
 assert( 3 == n2 );

The extraction operator >>= carries out widening conversions when no loss of data can occur, but data cannot be directed downward. If the extraction was successful, the operator returns sal_True, otherwise sal_False.

 Any any;
 sal_Int16 n = 3;
 any <<= n;
 sal_Int8 aByte = 0;
 sal_Int16 aShort = 0;sal_Int32 aLong = 0;
 // this will succeed, conversion from int16 to int32 is OK.
 assert( any >>= aLong );
 assert( 3 == aLong );
 // this will succeed, conversion from int16 to int16 is OK
 assert( any >>= aShort );
 assert( 3 == aShort 
 // the following two assertions will FAIL, because conversion 
 // from int16 to int8 may involve loss of data..
 // Even if a downcast is possible for a certain value, the operator refuses to work
 assert( any >>= aByte );
 assert( 3 == aByte );

Instead of using the operator for extracting, you can also get a pointer to the data within the Any. This may be faster, but it is more complicated to use. With the pointer, care has to be used during casting and proper type handling, and the lifetime of the Any must exceed the pointer usage.

 Any a = ...;
 if( a.getTypeClass() == TypeClass_LONG && 3 == *(sal_Int32 *)a.getValue() )

You can also construct an Any from a pointer to a C++ UNO type that can be useful. For instance:

 Any foo()
     sal_Int32 i = 3;
     if( ... )
     i = ..;
     return Any( &i, cppu::UnoType< sal_Int32 >::get() );

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