Type Mappings
Mapping of Simple Types
The following table shows the mapping of simple UNO types to the corresponding C++ types.
UNO | C++ |
---|---|
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 UNOstring
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 UNOstring
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::UnoTxpe
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). |