类型映射
简单类型的映射
下表所示为 UNO 简单类型对应的 C++ 类型映射。
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 |
由于历史原因,UNO 类型 boolean
被映射成某种 C++ 类型 sal_Bool
,该类型具有两个明确的值 sal_False
和 sal_True
,这两个值不必属于 C++ bool 类型。UNO boolean
、sal_False
和 sal_True
的值之间的映射很简单,但使用与 sal_False
和 sal_True
都不同的 sal_Bool
的任何可能值则是错误的。
UNO 整数类型被映射成 C++ 整数类型,且保证其范围至少与对应的 UNO 类型范围一样大。但是,C++ 类型的范围可能更大,在这种情况下,在 UNO 的环境内使用对应的 UNO 类型范围以外的值将会是错误的。目前,还不能为无法提供合适的整数类型的 C++ 环境创建 C++ 语言绑定,这些类型满足最小范围保证。
UNO 浮点类型 float
和 double
被映射成 C++ 浮点类型 float
和 double
,它们必须至少能够表示对应的 UNO 类型的所有值。但是,C++ 类型可能能够表示更多的值,因为实现定义了它们在 UNO 环境中的处理方式。目前,还不能为无法提供合适的 float
和 double
类型的 C++ 环境创建 C++ 语言绑定。
UNO char 类型被映射成 C++ 整数类型 sal_Unicode
,它保证范围至少从 0 到 65535。UNO char 的值以显式方式被映射成 sal_Unicode
。如果 sal_Unicode
的范围更大,则使用该范围以外的值就是错误的。
对于 C++ typedef 类型 sal_Bool
、sal_Int8
、sal_Int16
、sal_Int32
、sal_Int64
和 sal_Unicode,要保证对于同一个基本的 C++ 类型,任何两个类型都不是同义词。但是,该保证不能扩充到 sal_uInt8、sal_uInt16 和 sal_uInt32 三种类型。
字符串的映射
除以下两个细节以外,UNO 的 string 类型和 rtl::OUString 之间的映射很简单:
- 可以用 rtl::OUString 对象表示的字符串长度是有限的。在 C++ 语言绑定的环境中使用 UNO 的较长的 string 值是错误的。
- rtl::OUString 类型的对象可以表示 UTF-16 代码单元的任意序列,而 UNO 的 string 类型值是 Unicode 标量值的任意序列。目前为止,只有当某些个别的 UTF-16代码单元(名义上是范围为 D800-DFFF 的高低替代码点)没有对应的 Unicode 标量值,并因此在 UNO 的环境中被禁止,这才会有影响。例如,C++ 字符串
static sal_Unicode const chars[] = { 0xD800 }; rtl::OUString(chars, 1);
在此环境中是非法的,而字符串
static sal_Unicode const chars[] = { 0xD800, 0xDC00 }; rtl::OUString(chars, 2);
则是合法的。有关 Unicode 的详细信息,请访问 www.unicode.org。
类型 Type 的映射
UNO 类型 type 被映射成 com::sun::star::uno::Type
。它包含类型的名称和 com.sun.star.uno.TypeClass。该类型使您可以获取包含 IDL 中定义的所有信息的 com::sun::star::uno::TypeDescription
。对于某个给定的 UNO 类型,对应的 com::sun::star::Type
对象可以使用 cppu::UnoTxpe
类模板来获取:
// 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();
在表示 UNO 类型时,某些 C++ 类型不能用作 C++ 模板参数,或有些则含糊地表示一种以上的 UNO 类型。 这时 C++ 类型 cppu::UnoVoidType
、cppu::UnounsignedShortType
、cppu::UnoCharType
和 cppu::UnoSequenceType
可以用作 cppu::UnoType
的参数。
使用重载的 getCppuType 函数来获取 com::sun::star::uno::Type
是较旧的方式。现在这种方法已经不再使用(某些在模板代码中对 getCppuType
的使用未必会得到期望的结果),取而代之的是 cppu::UnoType
。
任意类型 Any 的映射
IDL any 被映射成 com::sun::star::uno::Any
。它包含一个任意 UNO 类型的实例。UNO 类型只能存储在 any 中,因为处理 any 时需要来自类型库的数据。
默认构造的 Any 包含 void 类型且不包含值。您可以使用运算符 <<= 将值指定到 Any,并可以使用运算符 >>= 获取值。
// 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 );
不存在数据丢失时,提取运算符 >>= 可以执行展宽转换,但不能向下转换数据。如果提取成功,该运算符返回 sal_True
,否则返回 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 );
除了使用运算符进行提取之外,您还可以获取一个指向 Any
内数据的指针。这可能更快,但使用起来较为复杂。在进行 强制类型转换和适当类型处理期间,使用指针时要谨慎,并且 Any
的生存期必须超过指针的使用寿命。
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). |