使用 UNO 接口
每个 UNO 对象都必须从接口 com.sun.star.uno.XInterface 继承。使用一个对象之前,需要了解其使用方式以及生存期。通过将 XInterface
指定为每个 UNO 接口的基接口,UNO 为对象通信打下了基础。由于历史原因,XInterface
的 UNOIDL 说明中列出了与 C++(或二进制 UNO)语言绑定中与 XInterface 有关的功能;其他语言绑定根据不同的机制提供类似的功能:
// module com::sun::star::uno interface XInterface { any queryInterface( [in] type aType ); [oneway] void acquire(); [oneway] void release(); };
acquire()
和 release()
方法通过引用计数来处理 UNO 对象的生存期。专业 UNO - UNO 概念 - UNO 对象的生存期 一节中介绍了有关引用计数的详细信息。无论何时引用 UNO 对象,所有当前语言绑定都内部处理 acquire()
和 release()
。
queryInterface()
方法获取该对象导出的其他接口。如果该对象支持类型参数指定的接口,调用程序就会请求实现该对象。type 参数必须表示一个 UNO 接口类型。调用可能返回请求类型的接口引用,或返回一个空 any
。在 C++ 或 Java 中,只需简单测试结果是否为 null。
当请求服务管理器创建一个服务实例时,我们无意中就遇到了 XInterface
:
XComponentContext xLocalContext = com.sun.star.comp.helper.Bootstrap.createInitialComponentContext(null); // initial serviceManager XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager(); // create a urlresolver Object urlResolver = xLocalServiceManager.createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", xLocalContext);
XmultiComponentFactory
的 IDL 规范显示:
// module com::sun::star::lang interface XMultiComponentFactory : com::sun::star::uno::XInterface { com::sun::star::uno::XInterface createInstanceWithContext( [in] string aServiceSpecifier, [in] com::sun::star::uno::XComponentContext Context ) raises (com::sun::star::uno::Exception); ... }
上面的代码说明的是 createInstanceWithContext()
提供给定服务的一个实例,但它仅返回一个 com.sun.star.uno.XInterface。然后,通过 Java UNO 绑定将其映射成 java.lang.Object。
要访问某项服务,需要知道该服务导出哪些接口。可从 IDL 引用中获得此信息。例如,对于 com.sun.star.bridge.UnoUrlResolver 服务,您会了解到:
// module com::sun::star::bridge service UnoUrlResolver: XUnoUrlResolver;
{{Note|对于新式服务,如 com.sun.star.bridge.UnoUrlResolver.html" class="external text">com.sun.star.bridge.XUnoUrlResolver</idle>。接下来,查询此接口的返回对象:
// query urlResolver for its com.sun.star.bridge.XUnoUrlResolver interface XUnoUrlResolver xUrlResolver = (XUnoUrlResolver) UnoRuntime.queryInterface(UnoUrlResolver.class, urlResolver); // test if the interface was available if (null == xUrlResolver) { throw new java.lang.Exception( "Error: UrlResolver service does not export XUnoUrlResolver interface"); } // use the interface Object remoteObject = xUrlResolver.resolve( "uno:socket,host=0,port=2002;urp;StarOffice.ServiceManager");
{{Note|对于新式服务,如 com.sun.star.bridge.UnoUrlResolver,有一种更好的方法可以获取其实例,请参阅 专业 UNO - UNO 语言绑定 - Java 语言绑定 - 类型映射 - 服务的映射 和 专业 UNO - UNO 语言绑定 - C++ 语言绑定 - 类型映射 - 服务的映射。
该对象决定是否返回接口。如果该对象不返回某项服务中指定的必需接口,则会出现一个错误。获取接口引用时,根据接口规范调用此引用。在服务管理器上实例化每项服务时,可以遵循此策略,以取得成功。
利用此方法,不仅可以通过服务管理器来获取 UNO 对象,而且可以通过一般接口调用来获取 UNO 对象:
// Module com::sun::star::text interface XTextRange: com::sun::star::uno::XInterface { XText getText(); XTextRange getStart(); .... };
返回的接口类型是在操作中指定的,因此可以直接在返回的接口上启动调用。通常,返回的是一个实现多个接口的对象,而不是实现某个具体接口的对象。
然后,就可以查询在给定的旧式服务中指定的其他接口的返回对象,在这里,给定的旧式服务为 com.sun.star.drawing.Text。
UNO 有许多普通接口。例如,接口 com.sun.star.frame.XComponentLoader:
// module com::sun::star::frame interface XComponentLoader: com::sun::star::uno::XInterface { com::sun::star::lang::XComponent loadComponentFromURL( [in] string aURL, [in] string aTargetFrameName, [in] long nSearchFlags, [in] sequence<com::sun::star::beans::PropertyValue> aArgs ) raises( com::sun::star::io::IOException, com::sun::star::lang::IllegalArgumentException ); };
现在很难找到除 XComponent
以外还支持哪些接口,因为返回的文档类型(Text、Calc、Draw 等)取决于接收到的 URL。
这些依赖关系将在本手册的相应章节进行介绍。
像 InstanceInspector
组件这样的工具就是获得某个具体对象支持哪些接口的快捷方法。InstanceInspector
组件包含可以用于在运行时检查某个具体对象的 OpenOffice.org SDK。不要依赖于某些具体对象的实现细节。如果除了服务说明中指定的接口以外,某个对象还支持其他接口,请查询相应的接口并执行调用。代码可能仅对这一明确的办公软件版本有效,而不适用于办公软件更新!
遗憾的是,服务规范中可能还存在错误。请向 openoffice.org 提供有关缺少的接口的反馈,以确保修正规范,而且您可以信赖此接口的支持。 |
queryInterface()
实现不能违反某些规范:
- 如果对某个特定对象进行
queryInterface()
调用返回给定类型的有效接口引用,则对该对象进行的任何后续queryInterface()
调用必须返回同一类型的有效引用。 - 如果对某个特定对象进行
queryInterface()
调用返回给定类型的空引用,则queryInterface()
必须始终返回同一类型的空引用。 - 如果对引用 A 进行
queryInterface()
调用返回引用 B,则对 B 进行类型 A 的queryInterface()
调用必须返回接口引用 A,或者对返回的引用进行的调用必须等同于对引用 A 进行的调用。 - 如果对引用 A 进行
queryInterface()
调用返回引用 B,则为 XInterface 对 A 和 B 进行的queryInterface()
调用必须返回同一接口引用(对象标识)。
不得违反这些规范,因为 UNO 运行时环境可以选择缓存 queryInterface()
调用。这些规则基本上与 MS COM 中 QueryInterface 的规则相同。
Content on this page is licensed under the Public Documentation License (PDL). |