接口类型的映射
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.XInterface
的 java.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 方法的签名没有影响。可以看出,out
和 inout
参数要特殊处理。为了便于解释,以 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 方法调用的语义是将任意 in
或 inout
参数的值从调用程序传递到被调用程序,如果方法没有标记为 oneway
并且执行成功终止,被调用程序将向调用程序传递回返回值和任意 out
或 inout
参数的值。因此,in
参数和返回值的处理很自然地映射成 Java 方法调用的语义。但是,UNO out
和 inout
参数则被映射成对应的 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). |