类型映射

From Apache OpenOffice Wiki
< Zh‎ | Documentation
Revision as of 09:25, 4 July 2008 by Jirong (Talk | contribs)

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


简单类型的映射

下表所示为 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_Falsesal_True,这两个值不必属于 C++ bool 类型。UNO booleansal_Falsesal_True 的值之间的映射很简单,但使用与 sal_Falsesal_True 都不同的 sal_Bool 的任何可能值则是错误的。


UNO 整数类型被映射成 C++ 整数类型,且保证其范围至少与对应的 UNO 类型范围一样大。但是,C++ 类型的范围可能更大,在这种情况下,在 UNO 的环境内使用对应的 UNO 类型范围以外的值将会是错误的。目前,还不能为无法提供合适的整数类型的 C++ 环境创建 C++ 语言绑定,这些类型满足最小范围保证。


UNO 浮点类型 floatdouble 被映射成 C++ 浮点类型 floatdouble,它们必须至少能够表示对应的 UNO 类型的所有值。但是,C++ 类型可能能够表示更多的值,因为实现定义了它们在 UNO 环境中的处理方式。目前,还不能为无法提供合适的 floatdouble 类型的 C++ 环境创建 C++ 语言绑定。


UNO char 类型被映射成 C++ 整数类型 sal_Unicode,它保证范围至少从 0 到 65535。UNO char 的值以显式方式被映射成 sal_Unicode。如果 sal_Unicode 的范围更大,则使用该范围以外的值就是错误的。


对于 C++ typedef 类型 sal_Boolsal_Int8sal_Int16sal_Int32sal_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::UnoVoidTypecppu::UnounsignedShortTypecppu::UnoCharTypecppu::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).
Personal tools
In other languages