ICE笔记(04):slice2cpp 及编译、运行

colorado

 

slice2cpp 命令行语法:
<compiler-name> [options] file…

1、通用的命令行选项是:
• -h, --help
显示帮助信息。
• -v, --version
显示编译器版本。
• -DNAME
定义预处理器符号NAME。
• -DNAME=DEF
定义预处理器符号NAME,其值为DEF。
• -UNAME
解除预处理器符号NAME 的定义。
• -IDIR
在#include 指令的搜索路径中增加目录DIR。
• E
在stdout上打印预处理器输出。
• --output-dir DIR
把生成的文件放进目录DIR。
• -d, --debug
打印调试信息,显示Slice分析器的操作。
• --ice
启用正常情况下保留的标识符前缀Ice。应该只在编译Ice 运行时的源码时使用这个选项。

Slice 编译器允许你编译不止一个源文件,所以你可以同时编译若干Slice 定义:
slice2cpp -I. file1.ice file2.ice file3.ice

2、slice2cpp特定命令行选项:
• --header-ext EXT
把生成的头文件扩展名从缺省的h 变成EXT 所指定的扩展名。
你也可以用全局元数据指令修改头文件扩展名:
[["cpp:header-ext:hpp"]]
// ...
每个源文件中仅能有一个这种指令。如果既在命令行上指定了头文件扩展名,又用元数据指令指定了头文件扩展名,则元数据指令优先。这确保了分别编译的Slice文件能得到正确的头文件扩展名(假定Slice文件包含一个相应的元数据指令)。例如:
// File example.ice
#include <Ice/BuiltinSequences.ice>
// ...
以如下命令行编译本文件
$ slice2cpp --header-ext=hpp -I/opt/Ice/include example.ice
生成example.hpp, 但是该文件中的 #include 指令包含了Ice/BuiltinSequences.h (而不是Ice/BuiltinSequences.hpp),因为BuiltinSequences.ice包含了元数据指令[[”cpp:header-ext:h”]]。
你通常不需要使用该元数据指令,仅当如下条件时该指令才是必须的:
• 你 #include 自己Slice文件集中的一个Slice文件。
• 被包含的 Slice文件是你要链接的库的一部分。
• 库带有被包含的Slice文件的头文件。
• 库头文件使用了与你自己代码不同的头文件扩展名。
例如,如果库使用.hpp作为头文件扩展名,但你自己的代码使用.h,库的Slice文件应该包含[[”cpp:header-ext:hpp”]]指令。(如果该指令丢失,你要为库的Slice文件加上它。)

• --source-ext EXT
把生成的源文件的文件扩展名从缺省的cpp 变成EXT 所指定的扩展名。

• --add-header HDR[,GUARD]
该选项为生成的源文件开头添加包含指定头文件的指令(先于任何其它包含指令)。如果指定GUARD,包含指令被指定标识符保护。例如: --add-header precompiled.h,__PRECOMPILED_H__
在生成源文件的开始产生上面的指令:
#ifndef __PRECOMPILED_H__
#define __PRECOMPILED_H__
#include <precompiled.h>
#endif
该选项可以为多个文件重复创建包含指令。如上例所推荐的那样,该选项主要是以编译器的预编译头机制整合生成的代码。

• --include-dir DIR
修改源文件中#include指令,为每个头文件添加DIR目录下的路径名。

• --impl
生成示范性的实现文件,这个选项不会覆盖已有文件。

• --depend
把makefile依赖信息打印到标准输出。指定该选项时不产生代码。输出在包含进makefile之前通常需要过滤;Ice构建系统为此使用了脚本config/makedepend.py。

• --dll-export SYMBOL
使用SYMBOL控制DLL输入、输出。该选项允许你在生成的代码中分别输入、输出全局符号。例如,用下面的命令编译Slice定义:
$ slice2cpp --dll-export ENABLE_DLL x.ice
会在x.h中产生如下额外的代码:
#ifndef ENABLE_DLL
# ifdef ENABLE_DLL_EXPORTS
# define ENABLE_DLL ICE_DECLSPEC_EXPORT
# else
# define ENABLE_DLL ICE_DECLSPEC_IMPORT
# endif
#endif
ICE_DECLSPEC_EXPORT 和 ICE_DECLSPEC_IMPORT 是平台特定的宏。例如,在Windows平台上,它们被分别定义为__declspec(dllexport) 和 __declspec(dllimport);在使用CC 5.5以上版本的Solaris平台上, ICE_DECLSPEC_EXPORT 被定义为 __global,ICE_DECLSPEC_IMPORT 是空。

你在命令行指定的,被生成代码用来输入、输出符号的符号名,在生成的编译单元外面也必须是对代码可见的。实际效果是,如果你要创建包含x.cpp的DLL,也要在DLL之外的编译单元中使用生成类型,要使用-DENABLE_DLL_EXPORTS来编译x.cpp,这样才可以输出相关符号。

• --checksum
为Slice定义生成检查和。

• --stream
为Slice类型生成流助手函数。

3、包含指令
由Slice到C++编译器生成的#include指令,若这种指令生成的语义没有被充分理解的话,会是混乱之源。生成的#include指令受命令行选项-I 和 --include-dir的影响;这些选项在下面详细讨论。--output-dir选项指定编译器将所有生成文件放入一个特定目录,但是不会影响生成代码的内容。

在头文件和源代码中#inlcude指令使用不同的语义生成。
⑴、头文件
大多数情况下,编译器缺省生成适当的#inlcude指令。例如,假定文件A.ice包含B.ice,使用如下的语句:
// A.ice
#include <B.ice>
假定两个文件都在当前工作目录下,我们如下运行编译器:
$ slice2cpp -I. A.ice
生成的文件A.h包含#include指令:
// A.h
#include <B.h>
如果为C++编译器指定合适的包含路径,编译将会正确进行。
类似地,考虑常见情况,A.ice包含子目录中的B.ice:
// A.ice
#include <inc/B.ice>
假定两个文件都在inc子目录中,我们如下运行编译器:
$ slice2cpp -I. inc/A.ice
编译器缺省输出产生了如下所示A.h中的#inlcude指令:
// A.h
#include <inc/B.h>
强调一下,这里需要配置C++编译器,以确保编译期间能够找到inc/B.h。

现在,让我们考虑一个更复杂的例子,我们不想要头文件中的#include指令匹配Slice文件。当Slice文件的组织结构不匹配应用程序的C++代码时,这是必须的。这种情况下,用户可能需要从它们创建的目录中重新定位生成的文件,且#include指令必须匹配新结构。

例如,让我们假定B.ice位于子目录slice/inc:
// A.ice
#include <slice/inc/B.ice>
但是,我们不想要slice子目录出现在生成的头文件的#include指令中,因此我们指定额外的编译选项-Islice:
$ slice2cpp -I. -Islice slice/inc/A.ice
生成的代码显示了该额外选项的影响:
// A.h
#include <inc/B.h>
如你所见,生成头文件中的#inlcude指令受到运行编译器时指定的包含路径的影响。特别是,当包含路径在生成的#inlcude指令中使用了路径名缩写时,更是如此。当编译#include指令时,编译器比较每个包含路径和已包含文件的路径。如果包含路径匹配已包含文件路径的前导部分,编译器就删除#include路径的前导部分。如果匹配一个以上的包含路径,编译器的选择是已包含文件中最短的路径。

例如,假定我们编译A.ice时使用下面选项:
$ slice2cpp -I. -Islice -Islice/inc slice/inc/A.ice
这种情况下,编译器对所有包含目录和已包含的文件slice/inc/B.ice进行比较,生成下面指令:
// A.h
#include <B.h>
选项-Islice/inc产生最短路径,因此包含文件(slice/inc/B.h)的缺省路径被替换为B.h。

通常,-I选项扮演两种角色:它允许预处理器定位包含的Slice文件,而且它还为你在生成#include指令时提供一定程度的控制。上面最后一个例子中,预处理器使用由-I.选项指定的包含路径定位slice/inc/B.ice。余下的-I选项不能帮助预处理器定位包含文件;它们只是给编译器某些提示。

最终,我们推荐谨慎使用包含路径。如果预处理器能够通过多个包含路径定位一个包含文件,它总是首先使用能够成功定位文件的包含路径。如果你要通过指定额外的-I选项来修改生成的#inlcude指令,你必须确保你包含路径的提示能够匹配预处理器选择的用于定位包含文件的包含路径。一般来说,你不应该指定预处理器通过多种途径定位文件的包含路径。

⑵、源文件
缺省情况下,编译器在源文件中生成的#include指令,仅使用包含文件的基本名称。当源文件和头文件驻留于同一目录时,该行为通常是合适的。
例如,假定A.ice包含子目录中的B.ice,下面列出了A.ice的一段代码:
// A.ice
#include <inc/B.ice>
我们使用下列命令生成源文件:
$ slice2cpp -I. inc/A.ice
经检查,我们看到源文件包含下面#include指令:
// A.cpp
#include <B.h>
但是,假定我们希望为生成的#include指令强制使用一个特定标准,以便它们兼容我们的C++编译器的现有包含路径设置。可以使用--include-dir选项修改生成的代码。例如,考虑如下的编译命令:
$ slice2cpp --include-dir src -I. inc/A.ice
源文件现在包含下列#include指令:
// A.cpp
#include <src/B.h>
通常包含文件中的任何前导路径被丢弃,--include-dir选项值被加入。

4、编译
以$ICE_HOME/demo/book/printer为例,Linux平台上编译运行的过程:
slice2cpp Printer.ice
生成Printer.h,Printer.cpp

编译服务器:
c++ -I. -I$ICE_HOME/include -c Printer.cpp Server.cpp
c++ -o server Printer.o Server.o -L$ICE_HOME/lib -lIce -lIceUtil

编译客户端:
c++ -I. -I$ICE_HOME/include -c Printer.cpp Client.cpp
c++ -o client Printer.o Client.o -L$ICE_HOME/lib -lIce -lIceUtil

在一个控制台窗口中运行:
./server
在另一个控制台窗口中运行:
./client

 

在Windows平台上,过程大体类似,只是可以使用VC++2008 Express的解决方案编译C++代码,更方便。

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
第 1 章引言 1 1.1 引言 1 1.2 Internet Communications Engine (Ice) 3 1.3 本书的篇章结 4 1.4 排字约定 4 1.5 源码示例 5 1.6 联系作者 5 1.7 Ice 支持 5 第 Ice 综述 7 第 2 章 Ice 综述 9 2.1 本章综 9 2.2 Ice 架构 9 2.3 Ice 服务 21 2.4 Ice 在架构上提供的好处 23 2.5 与 CORBA 的对比 25 第 3 章 Hello World 应用 33 3.1 本章综 33 3.2 编写 Slice 定义 33 3.3 编写使用 C++ 的 Ice应用 34 3.4 编写使用 Java的 Ice 应用 41 3.5 总结 48 第 Ice 核心概念 51 第 4 章 Slice 语言 53 4.1 本章综 53 4.2 引言 53 4.3 编译 54 4.4 源文件 57 4.5 词法规则 59 4.6 基本的 Slice 类型 62 4.7 用户定义的类型 63 4.8 接口、操作,以及异常 70 4.9 类 92 4.10 提前声明 106 4.11 模块 107 4.12 类型 ID 109 4.13 Object 上的操作 110 4.14 本地类 111 4.15 Ice 模块 112 4.16 名字与作用域 113 4.17 元数据 117 4.18 使用 Slice 编译器 118 4.19 Slice 与 CORBA IDL 的对比 119 4.20 总结 127 第 5 章 一个简单文件系统的 Slice 定义 137 5.1 本章综 137 5.2 文件系统应用 137 5.3 文件系统的 Slice 定义 138 5.4 完整的定义 140 第 6 章 客户端的 Slice-to-C++ 映射 143 6.1 本章综 143 6.2 引言 143 6.3 标识符的映射 144 6.4 模块的映射 144 6.5 Ice 名字空间 145 6.6 简单内建类型的映射 146 6.7 用户定义类型的映射 146 6.8 常量的映射 150 6.9 异常的映射 151 6.10 运行时异常的映射 154 6.11 接口的映射 154 6.12 操作的映射 161 6.13 异常处理 167 6.14 类的映射 169 6.15 slice2cpp 命令行选项 183 6.16 与 CORBA C++映射比较 184 第 7 章开发 C++ 文件系统客户 189 7.1 本章综 189 7.2 C++ 客户 189 7.3 总结 194 第 8 章 客户端的 Slice-to-Java 映射 197 8.1 本章综 197 8.2 引言 197 8.3 标识符的映射 198 8.4 模块的映射 198 8.5 Ice Package 199 8.6 简单内建类型的映射 200 8.7 用户定义类型的映射 200 8.8 常量的映射 204 8.9 异常的映射 205 8.10 运行时异常的映射 206 8.11 接口的映射 207 8.12 操作的映射 213 8.13 异常处理 219 8.14 类的映射 220 8.15 Package 224 8.16 slice2java 命令行选项 225 第 9 章开发 Java 文件系统客户 229 9.1 本章综 229 9.2 Java 客户 229 9.3 总结 233 第 10 章 服务器端的 Slice-to-C++ 映射 235 10.1 本章综 235 10.2 引言 235 10.3 服务器端 main函数 236 10.4 接口的映射 247 10.5 参数传递 249 10.6 引发异常 251 10.7 对象体现 252 10.8 总结 257 第 11 章开发 C++ 文件系统服务器 261 11.1 本章综 261 11.2 实现文件系统服务器 261 11.3 总结 276 第 12 章 服务器端的 Slice-to-Java 映射 279 12.1 Chapter Overview 279 12.2 引言 279 12.3 服务器端 main函数 280 12.4 接口的映射 285 12.5 参数传递 287 12.6 引发异常 288 12.7 Tie 类 289 12.8 对象体现 292 12.9 总结 296 第 13 章开发 Java 文件系统服务器 297 13.1 本章综 297 13.2 实现文件系统服务器 297 13.3 总结 306 第 14 章 Ice 属性与配置 307 14.1 本章综 307 14.2 属性 307 14.3 配置文件 309 14.4 在命令行

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值