序列的映射

From Apache OpenOffice Wiki
< Zh‎ | Documentation
Revision as of 08:29, 14 July 2008 by Jirong (Talk | contribs)

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


Automation 中的数组具有一种特定类型:SAFEARRAY。当 UNO 函数将序列作为参数时,就要使用 SAFEARRAY 数组。在 C++ 中要创建 SAFEARRAY,请使用 Windows API 函数。C++ 名称也是 SAFEARRAY,但在其他语言中,可能以不同的方式命名。例如,在 VB 中,甚至不存在该类型,因为该类型被映射成一个普通的 VB 数组:

 Dim myarr(9) as String


JScript 则不同。它没有提供创建 SAFEARRAY 的方法。而是特有 Array 对象,就索引和访问其值而言,该对象可用作普通数组。该对象在内部用一个分发对象表示。JScript 提供 VBArray 对象,该对象将 SAFEARRAY 转换成可以进一步处理的 Array 对象。


Template:Documentation/Tip


UNO 不能识别多维序列。但是,序列的元素也可以是序列。这些“内部”序列的长度可以不同,但是多维数组中维的元素长度都是相同的。


要为序列的序列提供参数,必须创建包含 SAFEARRAYVARIANTSAFEARRAY。例如:

 //UNO method
 void foo([in] sequence< sequence< long > > value);
 
 
 Dim seq(1) As Variant
 Dim ar1(3) As Long
 Dim ar2(4) As Long 
 'fill ar1, ar2
 ...
 
 seq(0) = ar1
 seq(1) = ar2
 
 objUno.foo seq


数组序列与“外部”序列相对应并且包含两个 VARIANT,其中又包含不同长度的 SAFEARRAY

如果序列的元素长度都相同,也可以使用多维 SAFEARRAY:

 Dim seq(9, 1) As Long
 'fill the sequence 
 ...
 objUno.foo seq


请注意:与 C 相比,Visual Basic 使用的是列排序,即 C 语言中相当于 VB 数组的是

 long seq[2][10]

在 VB 中,最高维由最右边的数字表示。


此语言绑定指定“外部”序列与最高维相对应。因此,VB 数组 seq(9,1) 将映射成序列的序列,其中外部序列有两个元素,每个内部序列各有 10 个元素。


返回的序列将转换成包含 VARIANT 的 SAFEARRAY。如果返回包含序列的序列,则 VARIANT 又会包含 SAFEARRAY


要在 Jscript 中处理返回的 SAFEARRAY,请使用 VBArray 对象将 SAFEARRAY 转换成 JScript <cod>Array</code>。当从 UNO 调用 Automation 对象的方法并且参数为 SAFEARRAY 时,将在 UNO 端使用序列。序列的元素类型应按照默认映射与 SAFEARRAY 的元素类型相对应。如果不对应,桥会试图将元素转换成所需的元素类型。


如果参数是一个多维 SAFEARRAY,则都必须提供包含序列的序列。嵌套的序列数与维数相对应。由于维的元素长度相同,因此表示该维的序列长度也应该相同。例如,假定在 C 语言中可以将 SAFEARRAY 表示为

 long ar[2][10]


则外部序列必须有两个元素,其中包含的每个序列有 10 个元素。由于将数组传送回 UNO 时不明确,因此,将返回的序列映射成 VARIANT 中的 SAFEARRAY 并不理想 。但是,桥通过使用 UNO 类型信息,解决了此问题。例如,长整型数的返回序列将导致 VARIANT 中的 SAFEARRAY 包含长整型数值。当在某种方法中将 SAFEARRAY 作为 sequence<long > 类型的参数进行传递时,会对其进行相应的转换。但是,如果参数为 any,则桥就没有必要的类型信息,并且会将 SAFEARRAY 转换成 sequence<any>。也就是说,调用的方法接收到的 any 将包含 sequence<any>。如果现在方法希望 any 包含 sequence<long>,则可能会失败。如果存在接受 any 参数的方法对,如 getxxxsetxxx,这样也会导致混乱。可能会获取 SAFEARRAY 作为返回值,但是在相应的 setXXX 调用中无法使用该值。例如:

 //UNO IDL
 any getByIndex();
 void setByIndex([in] any value);
 
 'VB
 Dim arLong() As Variant 
 arLong = objUno.getByIndex() 'object returns sequence<long> in any
 objUno.setByIndex arLong 'object receives sequence<any> in any and may cause an error.


为解决此问题,需要将在值对象中包装参数 (专业 UNO - UNO 语言绑定 - Automation 桥 - 类型映射 - 值对象):

 'VB
 Dim arLong() As Variant 
 arLong = objUno.getByIndex() 'object returns sequence<long> in any
 
 Dim objValueObject As Object
 Set objValueObject = objServiceManager.Bridge_GetValueObject()
 objValueObject.set “[]long”, arLong
 
 objUno.setByIndex objValueObject 'object receives sequence<long>


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