接口类型的映射

From Apache OpenOffice Wiki
Jump to: navigation, search



UNO 接口类型被映射成一个同名的公共 Java 接口。与表示 UNO 序列、枚举、结构和异常类型的 Java 类不同,空引用对表示 UNO 接口类型的 Java 接口实际上是合法值,即 Java 空引用表示 UNO 空引用。


如果一个 UNO 接口类型继承一个或多个其他接口类型,则 Java 接口是对应的 Java 接口的子接口。UNO 接口类型 com.sun.star.uno.XInterface 很特殊:只有当该类型用作另一个接口类型的基类型时,它才被映射成 Java 类型 com.sun.star.uno.XInterface。在其他所有情况下(用作序列类型的组件类型、结构或异常类型的成员或者接口方法的参数或返回类型时),它都被映射成 java.lang.Object。然而,该类型的有效 Java 值只是 Java 空引用和对实现 com.sun.star.uno.XInterfacejava.lang.Object 这些实例的引用。


如下形式的 UNO 接口属性

 [attribute] Type Name { 
     get raises (ExceptionG1, ..., ExceptionGM);
     set raises (ExceptionS1, ..., ExceptionSM);
 };

用两种 Java 接口方法表示

 Type getName() throws ExceptionG1, ..., ExceptionGM;
 void setName(Type value) throws ExceptionS1, ..., ExceptionSM;

如果属性被标记为 readonly,则没有设置方法。属性是否被标记为 bound 对生成的 Java 方法的签名没有影响。


如下形式的 UNO 接口方法

 Type0 name([in] Type1 arg1, [out] Type2 arg2, [inout] Type3 arg3) 
             raises (Exception1, ..., ExceptionN);

用 Java 接口方法表示

 Type0 name(Type1 arg1, Type2[] arg2, Type3[] arg3) 
             throws Exception1, ..., ExceptionN;


UNO 方法是否被标记为 oneway 对生成 Java 方法的签名没有影响。可以看出,outinout 参数要特殊处理。为了便于解释,以 UNOIDL 定义为例

 struct FooStruct { 
     long nval;
     string strval;
 };
 
 interface XFoo {
     string funcOne([in] string value);
     FooStruct funcTwo([inout] FooStruct value);
     sequence<byte> funcThree([out] sequence<byte> value);
 };


UNO 方法调用的语义是将任意 ininout 参数的值从调用程序传递到被调用程序,如果方法没有标记为 oneway 并且执行成功终止,被调用程序将向调用程序传递回返回值和任意 outinout 参数的值。因此,in 参数和返回值的处理很自然地映射成 Java 方法调用的语义。但是,UNO outinout 参数则被映射成对应的 Java 类型的数组。每个这样的数组都必须至少有一个元素(即其长度至少必须为 1;实际上,其长度没有必要更大。)因此,与 UNO 接口 XFoo 对应的接口如下:

 public interface XFoo extends com.sun.star.uno.XInterface { 
     String funcOne(String value);
     FooStruct funcTwo(FooStruct[] value);
     byte[] funcThree(byte[][] value);
 }


下面说明如何将 FooStruct 映射到 Java:

 public class FooStruct {
     public int nval;
     public String strval;
     
     public FooStruct() {
         strval="";
     }
 
     public FooStruct(int nval, String strval) {
         this.nval = nval;
         this.strval = strval;
     }
 }


将一个值作为 inout 参数提供时,调用程序必须将输入值写到数组的索引 0 对应的元素中。当函数返回成功时,索引 0 对应的值反映输出值,该值可以是未修改的输入值、输入值的已修改副本或一个全新的值。对象 obj 实现 XFoo

 // calling the interface in Java
 obj.funcOne(null);                          // error, String value is null
 obj.funcOne("");                            // OK
 
 FooStruct[] inoutstruct= new FooStruct[1];
 obj.funcTwo(inoutstruct);                   // error, inoutstruct[0] is null
 
 inoutstruct[0]= new FooStruct();            // now we initialize inoutstruct[0]
 obj.funcTwo(inoutstruct);                   // OK

当方法接受作为 out 参数的一个自变量时,必须提供一个值,而且必须放在数组的索引 null 处。

 // method implementations of interface XFoo
 public String funcOne(/*in*/ String value) {
     assert value != null;                           // otherwise, it is a bug of the caller
     return null;                                    // error; instead use: return "";
 }
 
 public FooStruct funcTwo(/*inout*/ FooStruct[] value) {
     assert value != null && value.length >= 1 && value[0] != null;
     value[0] = null;                                // error; instead use: value[0] = new FooStruct();
     return null;                                    // error; instead use: return new FooStruct();
 }
 
 public byte[] funcThree(/*out*/ byte[][] value) {
     assert value != null && value.length >= 1;
     value[0] = null;                               // error; instead use: value[0] = new byte[0];
     return null;                                   // error; instead use: return new byte[0];
 }


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