使用 UNO 接口

From Apache OpenOffice Wiki
Jump to: navigation, search



每个 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。不要依赖于某些具体对象的实现细节。如果除了服务说明中指定的接口以外,某个对象还支持其他接口,请查询相应的接口并执行调用。代码可能仅对这一明确的办公软件版本有效,而不适用于办公软件更新!


Documentation note.png 遗憾的是,服务规范中可能还存在错误。请向 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).
Views
Personal tools
Navigation
Tools
In other languages