Gnorba 库

介绍

gnorba 主要是围绕两个 corba 函数(CORBA_ORB_init 和 CORBA_ORB_resolve_initial_services)的一个包装(wrapper),并实现了一个活动目录(Activation Directory)。活动目录是一个文件系统,它持有可得到的在一个机器上的 CORBA 服务器的一个列表,这些服务器不是必须运行的。  

初始化

GNOME 应用程序通常有一个 GTK 图形界面。 GTK 使用一个特定的事件循环来处理所有的 X 服务器和它自己的事件。 ORBit 也有自己的事件循环。这意味着图形应用程序需要一个让两个循环一起运行的方式。这是基础的,因此需要做一些特殊的初始化。

使用了 gnome_CORBA_init 函数、它是围绕 CORBA_ORB_init 和 gnome_init 函数的一个简单的包装。它将把  ORBit 事件循环集成到 GTK 自己的事件循环中。下面的代码演示了它的使用:

#include <orb/orbit.h>
#include <libgnorba/gnorba.h>
#include <gnome.h>

int main (int argc, char **argv)
{
  CORBA_ORB orb;
  CORBA_Environment ev;

  CORBA_exception_init (&ev);
  orb = gnome_CORBA_init ("a simple gnorba test prgm", 
                          "v 1.0", 
                          &argc, 
                          argv, 
                          &ev);

  return 0;
}

命名服务

我们已经看到了为什么 ORBit 的名字服务有一些问题:1) 你需要手动的启动 orbit-name-server。2) 名字服务不与 CORBA_ORB_resolve_initial_reference 一起工作。

GNOME 实现了 gnome_name_service_get 函数,这个函数返回一个表示根 NamingContext 的 CORBA::Object representing the Root NamingContext,而这个对象引用本来应该用 CORBA_ORB_resolve_initial_references 返回。它的使用是直接的:

#include <orb/orbit.h>
#include <libgnorba/gnorba.h>
#include <gnome.h>

int main (int argc, char **argv)
{
  CORBA_Object name_server;
  CORBA_Environment ev;

  CORBA_exception_init (&ev);
  orb = gnome_CORBA_init ("a simple gnorba test prgm", 
                          "v 1.0", 
                          &argc, 
                          argv, 
                          &ev);


  name_server = gnome_name_service_get ();
  return 0;
}

这个函数将首先检查是否启动了一个名字服务器,如果没有启动就启动它,接着返回对象的对象引用。为此它要在 X 窗口系统的根窗口中存储信息,这就是向 ORBit 代码中填加这个函数的原因:它不能在图形 X 系统之外工作。

GOAD

介绍

GOAD 允许你列出准备运行的 CORBA 服务器并最终启动它们。举个例子,GNOME 的帮助系统就在 GOAD 仓库中列出、并可以通过激活(activating)来启动它。

这是必须的的原因是 CORBA 提供了激活服务器一种方式,但要激活,它们需要内存供给,这可能导致内存短缺。CORBA 中解决(get around)这个问题的方式是使用仆从管理器,但在整体上,GOAD 是更简单的解决方法。

可能查看这个仓库而不需要编任何代码:可以用与 libgnorba 一起发布的"goad-browser"程序来列出服务器并允许你激活它们。

使用 GOAD

要使用 GOAD,你需要访问一个简单但强有力的 API:

5-1. GOAD API

函数的名字函数的用途
goad_server_list_get这个函数返回一个列出在 GOAD 上的所有服务器的 GoadServerList *。
goad_server_list_free它释放由 goad_server_list_get 分配来的 GoadServerList 。
goad_server_activate这个函数将返回对应于作为一个参数传递的Goad Server 的相应的 CORBA_Object。
goad_server_activate_with_id这个函数将最终调用 goad_server_activate,但它还需要其他参数。
goad_server_activate_with_repo_id这个函数将最终调用 goad_server_activate,但它还需要其他参数。

这些函数与一些众所周知的结构一起工作: GoadServer 和 GoadServerList。

typedef struct {
          GoadServerType type;
          /* only GOAD_ACTIVATE_NEW_ONLY
             currently parsed in */
          GoadActivationFlags flags; 
          char     **repo_id;
          char     *server_id;
          char     *description;

          /*
           * Executable/shlib path, relayer IOR, 
           * whatever. This field may disappear 
           * at any time. You have been warned ;-)
           */
          char     *location_info;
  } GoadServer;

typedef struct {
    GoadServer *list;
    GHashTable *by_goad_id;
  } GoadServerList;

typedef enum {
          GOAD_SERVER_SHLIB = 1,
          GOAD_SERVER_EXE = 2,
          GOAD_SERVER_RELAY = 3,
          GOAD_SERVER_FACTORY = 4
  } GoadServerType;

typedef enum {
          /* these two are mutually exclusive */
          /* prefer shlib activation */
          GOAD_ACTIVATE_SHLIB = 1 << 0,
          /* prefer remote activation */
          GOAD_ACTIVATE_REMOTE = 1 << 1,  

          /* these two are mutually exclusive */
          /* Only do lookup in name
           * service for currently running
           * version. */
          GOAD_ACTIVATE_EXISTING_ONLY = 1 << 2,
          /* No lookup in name service. */
          GOAD_ACTIVATE_NEW_ONLY = 1 << 3,
          /* Just make sure that the object is running */
          GOAD_ACTIVATE_ASYNC = 1 << 4 
  } GoadActivationFlags;

下面是使用它们的代码的例子...

/* this function will return a clist widget 
 * which holds a list of the available servers
 */
GtkWidget *get_list (void)
{
  GoadServer *tmp;
  char *titles[2] = {"Description", "Activated ?"};
  GtkWidget *clist;
  GtkWidget *popup;

  list = goad_server_list_get ();
  tmp = list->list;

  clist = gtk_clist_new_with_titles (2, titles);
  gtk_signal_connect (GTK_OBJECT(clist), 
                      "select_row",
                      select_row_cb, 
                      NULL);
  gtk_clist_set_column_width (GTK_CLIST(clist), 0, 250);
  gtk_clist_set_column_width (GTK_CLIST(clist), 1, 30);
  gtk_clist_set_selection_mode (GTK_CLIST(clist), 
                                GTK_SELECTION_EXTENDED);
  gtk_widget_show (clist);

  for (tmp=tmp; tmp->repo_id; ++tmp) {
    gchar *table[2] = {tmp->description, is_active(tmp)?"yes":"no"};
    gtk_clist_append(GTK_CLIST(clist), table);
  }

  return (clist);
}

现在要做的正确的事就是浏览 goad-browser 的源代码:gnome-libs/gnorba/goad-browser.c 。

向 GOADservers 添加服务

要向 GOAD 中添加服务,你应该使用 .gnorba 文件。在 GNOME 初始化时 GOAD 启动,GOAD 读特定目录(/etc/CORBA 或 /usr/etc/CORBA 或...)。在这个目录中的每个文件可以包括一个或更多服务器定义。这里是一个这样的文件: 

[gnome_panel]
type=exe
repo_id=IDL:GNOME/Panel:1.0
description=GNOME Panel
location_info=panel

这些信息到 GoadServer 结构的字段的映射是直接了当的。开始的[gnome_panel] 是将要在名字服务器上注册的服务器的名字。第二个 type=exe 被 GOAD 内部使用、决定如何启动服务器。最后的 location_info=panel 被用于找到相应的服务器实现。这里的 gnome_panel 是在 panel 可执行文件中被实现的。


PrevHomeNext
CORBA in GNOMEUpThe GNOME Desktop