使用 UNO 接口

From Apache OpenOffice Wiki
Jump to: navigation, search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.



每个 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;

这意味着您在服务管理器上订购的服务必须支持

  // 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|对于新式服务,如 <idl>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|对于新式服务,如 <idl>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).
Personal tools
In other languages