秋梦无痕

一场秋雨无梦痕,春夜清风冻煞人。冬来冷水寒似铁,夏至京北蟑满城。

Avatar

MICO学习笔记

发信人: Mentoya (Javing...), 信区: DOC
标 题: MICO学习笔记
发信站: BBS 水木清华站 (Thu Dec 18 10:13:48 2003), 站内

主要是参考<MICO: 开源CORBA的设计与实现>一书.
=============================
用Visual C++ 开发MICO程序
=============================
一.PATH环境变量
假设MICO的BIN目录在d:\mico\win32-bin下,则设置PATH环境变量:
PATH = d:\mico\win32-bin;%PATH%
注:以下均假设mico的bin目录为:d:\mico\win32-bin

二.所需的版本
最好是Visual C++6.0 SP3以上版本。

三.设置Visual C++
1.设置路径
添加Include path:
d:\mico\win32-bin\include\windows
d:\mico\win32-bin\include
添加Library path:
d:\mico\win32-bin\lib
添加Executable path:
d:\mico\win32-bin
注:include路径必须在路径列表的顶部。

2.项目设置
首先在Project→Settings左上角的Setting For中选择All Configurations。

编译器
在C++标签→General→Preprocessor definitions中添加:
_WINDOWS
在C++标签→Code Generation→Use run-time library处选择:
Debug Multithreaded DLL(Debug版)

Multithreaded DLL(Release版)

链接器
在Link标签→General→Object/library modules中添加:
micoXXX.lib

wsock32.lib
如果用到CORBA服务,则要添加
micocossXXX.lib
其中XXX是3个没有点的mico的数字版本号。

3.将IDL编译器集成到IDE中
将IDL编译器集成到IDE中的好处是,IDE可以注意到IDL文件的变化,并且在必要的时候自动重新编译IDL文件。
1) 添加IDL文件到项目中
2) 在Project→Settings中选择Custom Build标签,然后输入:
idl -c++suffix=cxx [其它参数] $ (InputPath)

=============================
MICO文件说明
=============================
一.可执行文件
MICO的可执行文件位于d:\mico\win32-bin目录中。具体说明如下:

IDL.EXE
idl编译器
MICOD.EXE
BOA daemon程序。
NSD.EXE
名字服务daemon程序
NSADMIN.EXE
名字查看工具。
IRD.EXE
接口存储库(Interface Repository)daemon程序。
IORDUPE.EXE
IOR解析器。
IMR.EXE
实现存储库(Implementation Repository)daemon程序。
EVENTD.EXE
实现服务daemon程序。
TRADERD.EXE
交易服务daemon程序。
CONTAINMENTD.EXE
MICO-CPP.EXE
NODED.EXE
PROPERTYD.EXE
PROXYD.EXE
RADOMD.EXE
REFERENCED.EXE
TRAVERSALD.EXE

二.动态链接库(DLLs)
MICO237.DLL
MICO应用程序所需的动态链接库。
IDL237.DLL
MICO IDL编译器所需的动态链接库。

三.C++头文件和静态库文件
分别位于d:\mico\win32-bin\include和d:\mico\win32-bin\lib目录下
=============================
IDL编译器使用说明
=============================
一.IDL命令的各选项的说明:
--help
给出所有支持的命令行选项的概述
--version
显示MICO版本
--config
显示一些重要的配置信息
--D<define>
定义一个预处理宏。该选项类似于大部分C编译器的-D开关。
-I<path>
为#include指令定义一个查询路径。
--no-exceptions
在idl生成的代码中禁止异常处理。仍然生成异常类型的代码,但是抛出的异常将导致一个错误信息,并退出程序。该选项只能和--codegen-c++一起使用。默认为关闭。
--codegen-c++
根据IDL到C++语言的映射标准,生成以扩展名为.cc和.h的文件,文件名和idl的相同。本选项是默认值。
--no-codegen-c++
不生成C++代码
--codegen-idl
将idl文件转换成标准的IDL格式,它将自动为idl文件添加版权说明、哨兵等。并且需要用--name来指定新生成的idl的文件名。例:idl --codegen-idl --name acc account.idl 新生成的idl文件名为:acc.idl
-no-codegen-idl
默认值。
--c++-impl
为所有IDL规范中的接口产生一些默认的C++实现类。可以减少用户的输入,防止出错。
--c++-suffix=<suffix>
决定了生成的C++文件的扩展名。例:idl --c++-suffix cxx account.idl
--hh-suffix=<suffix>
决定了生成的头文件的扩展名。
--c++-skel
生成一个只包含服务器所需要代码的代理文件,其后缀为_skel.cc。在默认情况下,代码都放入标准的C++实现文件中。
--relative-paths
#include中的文件使用相对路径
--emit-repoids
该选项只能和--codegen-idl选项一起使用。它导致放入#pragma指令,它联系着每个IDL中接口的存储库标识(Implementation Repository Id)。
--do-not-query-server-for-narrow
如果使用这个选项,则IDL编译器忽略所有_narrow()方法的特定代码,它们禁止在运行时查询远处服务器。在特定环境下,这是允许的,可以产生更有效的运行时特性。
--feed-ir
在命令行中指定的IDL被放入接口库中。该选项需要运行ird daemon。
--feed-include-defs
和--feed-ir一起使用。它将包含文件中的IDL也放入到接口库中。在默认情况下,只将IDL主文件的定义放入接口库中。
--repo-id=<id>
根据接口库中的信息来生成代码,而不是根据文件中的信息。这个选项需要运行ird。参数id是一个存储库标识,而且必须代表一个CORBA模块。
--name=<prefix>
指定生成文件的文件名。如果输入从接口库中取得,则需要设置这个选项。如果输入从文件取得,则默认的文件名和idl文件的文件名相同。例:idl --name acc account.idl 生成的文件名将是:acc.cc和acc.h
--pseudo
为伪接口生成代码。但是不生成任何stub、skeleton以及marshalling的代码。
--any
为idl中的类型提供any支持。该选项隐含-typecode选项。
--typecode
为用户定义的类型生成typecode代码。
--poa
生成 POA实现的代码。默认值。
--no-poa
不生成POA实现的代码。
--no-poa-ties
当使用POA实现时,该选项不生成Tie实现类。
--boa
使用BOA实现
--no-boa
不用BOA实现
--gen-include-defs
为通过使用#include指令包含的IDL声明生成代码。
--gen-full-dispatcher
Usually the skeleton class generated for an interface contains only the dispatcher for the operations and attributes defined in this interface. With this option, the dispatcher will also include operations and attributes inherited from all base interfaces.

二.一些例子

idl -c++-suffix cxx -hh-suffix h -any -c++-impl -boa --no-poa account.idl
BOA实现,且不要POA实现代码;
提供对Any的支持;
C++文件的扩展名为.cxx,头文件的扩展名为.h;
生成空的实现类的代码。

idl --no-codegen-c++ --codegen-idl --emit-repoids --name accountNew account.idl
不生成C++代码,将IDL文件转换为标准的IDL格式;
生成用户定义类型和接口及方法的存储库标识。
指定新生成的文件名为:accountNew.idl。

idl -c++-suffix cxx -hh-suffix h -any -c++-impl account.idl
POA实现。
=============================
ORB初始化
=============================
ORB是作为一个静态库(2.3.7版本为mico237.lib)链接到MICO应用程序中的。

一.ORB的初始化
在使用MICO前,必须要对ORB进行初始化。
int main (int argc, char *argv[])
{
CORBA::ORB_var orb = CORBA::ORB_init (argc, argv, "mico-local-orb");
//…
}
通过这种方法,ORB就可以访问应用程序的命令行参数。ORB估算之后,将它理解的命令行参数删除,所以应用程序就不必考虑它们了。目前,"mico-local-orb"是MICO唯一支持的ORB标识。

二.ORB的命令行参数详解
可以将ORB的命令行参数放入home directory(UNIX/LINIX)中的一个名为.micorc的文件中。需要指出的是,在命令行中给出的参数将覆盖.micorc中的设置。在windows平台上的设置方法见附录。

-ORBNoIIOPServer
不激活IIOP服务器。IIOP服务器可以使其它进程通过IIOP协议调用本进程的对象。如果你不想让其它进程调用本进程的对象,则使用本选项。默认值是激活IIOP服务器。
-ORBNoIIOPProxy
不激活IIOP代理。IIOP代理可以使本进程通过IIOP协议调用其它进程中的对象。默认值是激活IIOP代理。
-ORBIIOPAddr<address>
设置IIOP服务器运行的地址。如inet:<host name>:<port number>格式的地址。如果不指定该选项,则IIOP服务器将选择一个不用的地址。欲使IIOP服务器监听多个地址,则可以多次使用这个选项。
-ORBIIOPBlocking
使IIOP使用sockets的阻塞模式。这样将获得额外的性能,但是嵌套方法调用在这种模式下不工作。
-ORBId<ORB Identifier>
指定ORB的标识。在当前版本的MICO中,只支持mico-local-orb。
-ORBImplRepoIOR<impl repository IOR>
为ORB将要使用的实现存储库(Implementation Repository,IMR)指定一个字符串形式的IOR。
-ORBImplRepoAddr <impl repository address>
指定运行的IMR的地址。ORB尝试用给定的地址将一个实现绑定到IMR上。如果绑定失败,或者既没有指定-ORBImplRepoAddr也没有指定-ORBImplRepoIOR,则ORB将运行一个本地IMR。
-ORBIfaceRepoIOR <interface repository IOR>
指定接口存储库的IOR。功能类似于-ORBImplRepoIOR。
-ORBIfaceRepoAddr <interface repository address>
指定接口存储库的地址。功能类似于-ORBImplRepoAddr。
-ORBNamingIOR <naming service IOR>
指定名字服务器的IOR。
-ORBNamingAddr <naming address>
指定名字服务器的地址。
-ORBInitRef <Identifier>=<IOR>
将给定的IOR值附给由Identifier指定的初始引用。Sets the value for the initial reference by the name of identifer to the given object reference. This mechanism can be used both for custom and for standard initial references.
-ORBDefaultInitRef <IOR-base>
Defines a location for initial references. IOR-base is an iioploc- or iiopname-Style object reference. When a previously unknown initial reference is searched for using resolve_initial_references(), the searched-for identifier is concatenated to the IOR-base string to produce the service's location.
-ORBNoResolve
不要将一个IP地址解析为主机名。Use dotted decimal notation instead.
-ORBDebugLevel <level>
指定调试级别。<level>为非负整数。数值越大,在cerr上输出的调试信息就越多。
-ORBBindAddr <address>
指定bind(const char*)函数应该绑定的地址。可以重复使用该选项来指定多个绑定地址。
-ORBConfFile <rcfile>
指定读取附加命令行选项的文件。默认是~/.micorc。
-ORBNoCodeSets
不要在IOR中添加代码集信息。因为代码集转换是CORBA2.1的特征。当和不符合CORBA2.1标准的ORB对话时,这个选项也许有用。此外,不添加代码集信息可以获得一些额外的速度。
-ORBNativeCS <pattern>
为应用程序使用的字符和字符串指定代码集。<pattern>是一个shell-like pattern,并且它必须与OSF代码集注册表中的description域匹配。该代码集注册表在admin/code_set_registry.txt和admin/mico_code_set_registry.txt文件中。例如*8859-1*将使ORB使用代码集ISO-8859-1(Latin-1)作为本地的字符代码集。当与不同代码集的应用程序对话时,ORB使用这个信息自动转换字符和字符串。如果不指定-ORBNativeCS选项,则默认使用ISO-8859-1代码集。
-ORBNativeWCS <pattern>
类似-ORBNativeCS,但是它是为宽位字符和宽位字符串指定代码集。默认是UTF-16,一个Unicode的16位编码方式。
=============================
接口存储库(IR)
=============================
接口存储库由ird来实现。所有的MICO应用程序可以使用相同的接口存储库(Interface Repository,IR)。

一.指定ird运行的地址
用命令行选项-ORBIfaceRepoAddr指定MICO应用程序使用那一个IR,而-ORBIIOPAddr选项指定ird程序应该绑定的地址。
例:欲使ird运行于192.168.82.213:8888,则用以下语句运行idr:
idr -ORBIIOPAddr inet:192.168.82.213:8888

在运行用户编写的MICO应用程序时,用-ORBIfaceRepoAddr来指定ird的地址:
My_MICO_Application -ORBIfaceRepoAddr inet:192.168.82.213:8888

简单起见,可以在.micorc文件中放入选项: -ORBIfaceRepoAddr inet:192.168.82.213:8888
然后只运行My_MICO_Application就可以了。

二.ird的命令行参数
--help
显示所有支持的命令行参数的列表。
--db<database file>
当ird退出时,指定ird将接口存储库保存在<database file>指定的文件中。通过ctrl+c或SIGTERM信号可以关闭ird。以后当ird重新启动时,它将读取-db选项指定的文件来恢复IR中的内容。数据库文件的内容是普通的ASCII格式。
=============================
名字服务
=============================
一.名字服务器(nsd)
从名字到程序的绑定被保存在一个名字服务器daemon(nsd)中。它控制一组命名上下文(name context)对象,并且回答客户端的询问。可以有多于一个名字服务器。
nsd通常通过micod自动运行。所以为了使用它,必须首先运行micod,在IMR中,用imr工具为命名服务创建一个entry(即将命名服务器注册到IMR中),并且使用-ORBNamingAddr选项将命名服务的地址传给客户。

二.管理(nsadmin)
MICO命名服务还带有一个管理工具nsadmin。它为COSS命名服务提供了一个用户接口。如果它不带命令行选项调用(除了ORB特定的选项,如-ORBNamingAddr),则将进入交互模式,并显示一个提示,并等待用户输入。
在nsadmin支持的命令中,上下文和绑定名字遵守Unix文件系统的语法:使用下划线分开上下文的名字;以下划线开始的名字从nsd中根开始(相当于绝对路径),否则相当于当前的上下文(相当于相对路径);..代表上一级的上下文。下面是nsadmin支持的命令,这些命令既可以在命令行中指定,也可以用在交互模式(exit命令除外)。在nsadmin中还支持类似doskey的功能。

help
给出所有支持命令的描述。
pwd
显示当前上下文的路径。
ls <binding-or-context>
如果<binding-or-context>是一个绑定,则它显示相关的字符串格式的IOR;如果<binding-or-context>是一个上下文,则显示上下文的内容;如果<binding-or-context>被省略,则显示当前上下文的内容。
cd <context>
使<context>成为当前上下文。支持cd..,cd/等。
mkdir <context>
创建一个新的上下文。
bind <binding> <stringified-IOR>
将<binding>绑定到指定的<stringified-IOR>。
rm <binding-or-context>
删除给定的绑定或上下文。如果指定的参数是一个上下文,则所有的子上下文也被删除。
exit
退出。只能用于交互模式。

三.nsd的命令行参数
--help
帮助。
--ior <IOR ref file>

--db <db file>
指定库文件。
--lb <load balancing : round_robin or random>

四.一个使用名字服务的例子
在使用名字服务的地方,需要包含名字服务的头文件:#include <mico/naming.h>
在工程设置中,要添加micocoss237.lib库文件。
1.服务器端(使用的是BOA代码)
服务器端用bind()在名字服务器中注册:

//…
Account_ptr acc = new Account_impl();
CORBA::Object_var nsobj = orb->resolve_initial_reference("NamingService");
CosNaming::NamingContext_var nc = CosNaming::Namingcontext::_narrow(nsobj);
CosNaming::Name name;
name.length(1);
name[0].id = CORBA::string_dup("myAccount");
name[0].kind = CORBA::string_dup("");
nc->bind(name, acc);
boa->impl_is_ready(CORBA::ImplementationDef::_nil());
//…

首先通过resolve_initial_reference("NamingService")取得名字服务的对象引用(通过-ORBNamingAddr指定名字服务器的地址);
然后将它紧缩为NamingContext类型。
最后用bind()方法为Account对象建立一个新的绑定。也可以用rebind()方法,它的好处是如果指定的name存在的话,将不会产生异常,而是直接用新的值覆盖。

2.客户端(使用的是BOA代码)
客户端用resolve()方法来查询名字服务器。
//…
CORBA::Object_var nsobj = orb->resolve_initial_references("NameService");
CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(nsobj);
CosNaming::Name name;
name.length (1);
name[0].id = CORBA::string_dup ("myAccount");
name[0].kind = CORBA::string_dup ("");
CORBA::Object_var obj;
try {
obj = nc->resolve (name);
} catch (CosNaming::NamingContext::NotFound &exc) {
//…
} catch (CosNaming::NamingContext::CannotProceed &exc) {
//…
} catch (CosNaming::NamingContext::InvalidName &exc) {
//…
}
Account_var client = Account::_narrow(obj);
//…

3.运行本例
建立.micorc文件,指定-ORBImplRepoAddr和-ORBNamingAddr。

-ORBImplRepoAddr inet:192.168.82.213:12456
-ORBNamingAddr inet:192.168.82.213:12456

启动micod,并且告诉它IIOP协议使用的地址:
micod -ORBIIOPAddr inet:192.168.82.213:12456

使用IMR来注册命名服务和Account服务器。
imr create NameService shared /…/nsd IDL:omg.org/CosNaming/NamingContext:1.0
imr create Account shared /…/server IDL:Account:1.0
这样,当客户或服务器有请求是,就可以自动运行nsd了。

现在的问题是,Account服务器是作为共享方式注册的,除非有客户想与它连接,否则它不会启动。但是在Account服务器和命名服务器建立一个绑定之前,客户无法定位这个Account服务器。所以,我们需要手工激活这个服务器:
imr activate Accout

一个名字服务的具体例子在demo\service\naming目录下。
=============================
附录
=============================
一.IOR及工具IORDUMP的使用
IOR包含客户与服务器联系所需的所有信息。

在不同的系统上IOR看起来会有所不同。因为它包含的信息中的一部分决定于主机名、端口号和服务器对象的对象标识。

用工具iordump可以显示IOR的内容。

iordump工具的使用方法:

D:\temp\MICO>iordump --help
usage:
iordump -- reads IOR from stdin
iordump IOR -- reads IOR from command line
iordump repoid [tag] -- binds to repoid using tag

例:
iordump IOR:
010000001000000049444c3a4d79436c6173733a312e300002000000000000002c000000010100000f0000003139322e3136382e38322e32313300008e0400000c000000424f41c0a852d500000b48010100000024000000010000000100000001000000140000000100000001000100000000000901010000000000

将输出如下内容:
Repo Id: IDL:MyClass:1.0

IIOP Profile
Version: 1.0
Address: inet:192.168.82.213:1166
Location: corbaloc::192.168.82.213:1166/BOA%c0%a8R%d5%00%00%0bH%01
Key: 42 4f 41 c0 a8 52 d5 00 00 0b 48 01 BOA..R....H.

Multiple Components Profile
Components: Native Codesets:
normal: ISO 8859-1:1987; Latin Alphabet No. 1
wide: ISO/IEC 10646-1:1993; UTF-16, UCS Transformation Format 16 -bit form
Key: (empty)

二. 在Windows平台上.micorc的处理
1.设置环境变量HOME,MICO使用$HOME/.micorc文件作为MICO的配置文件。
2.用环境变量MICORC来指定一个文件作为MICO的配置文件。该方法将覆盖默认的$HOME/.micorc设置。如果令MICORC=NUL,则不使用配置文件。
例:

SET HOME=d:\mico\win32-bin
则MICO会使用文件d:\mico\win32-bin\.micorc作为它的配置文件。

SET MICORC=D:\CORBA\ORBTest\mico\Server\Debug\config.txt
则MICO使用文件D:\CORBA\ORBTest\mico\Server\Debug\config.txt作
为它的配置文件。

SET MICORC=NUL
则MICO不使用配置文件。

3.一个配置文件的例子:
-ORBImplRepoAddr inet:192.168.82.213:1722
-ORBNamingAddr inet:192.168.82.213:1722

注意:配置文件中,每行结束后必须要加回车。

您好!
我是在linux下用mico, 在运行demo/services/namingServic时,单机好用,双机时就不好用了,请教这是什么原因.
谢谢了!

评论已关闭