`

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++代码,更方便。

分享到:
评论

相关推荐

    gulp-ice-builder:Gulp插件,可自动将Slice文件编译为JavaScript

    slice2js gulp-ice-builder调用slice2js编译器。 您可以使用以下命令安装最新的 : npm install slice2js --save-dev 用法 const iceBuilder = require ( 'gulp-ice-builder' ) ; gulp . task ( "slice2js" , ( ) ...

    ice-builder-xcode:Shell脚本,可在Xcode中将Slice文件编译为C ++或Objective-C

    Xcode的Ice Builder Ice Builder for Xcode是一个命令行程序,可帮助将Slice文件编译为Xcode中的C ++或Objective-C。 它支持所有最新版本的Xcode。安装自制酒通过运行以下命令,使用Homebrew安装Ice Builder for ...

    npm-slice2js:Slice到JavaScript编译器的Npm软件包

    将Slice文件编译为JavaScript。 安装 npm install slice2js --save-dev 用法 var slice2js = require ( 'slice2js' ) ; 方法 slice2js.compile(args [, options]) 返回一个对象。 args Array 传递给slice2js...

    slice-ios:Slice iOS SDK

    Slice iOS SDK 通过开发人员可以访问用户的在线购买历史记录。 它通过处理电子邮件回执来工作,并且涉及商户和产品类别。 可用的资源包括订单,物料,装运等。 SliceSDK是在iOS上使用Slice API的便捷框架。 注意...

    eclipse Slice2Java

    eclipse Slice2Java 控件 jar ,eclipse Slice2Java 控件 jar

    ICE客户端与服务端通信Demo

    平台编译环境:VS2017 ICE版本:3.7.7 ICEbuilder:5.0.9 源码中有两套程序: Server:启动服务器,等待连接 。连接后可双方通信 Client:连接服务器,与服务器通讯。 Slice: 手写几个接口即可。

    Zeroc ICE中间件slice2java的ant脚本

    NULL 博文链接:https://zhaoningbo.iteye.com/blog/1071365

    ICE分布式程序设计中文版

    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 ...

    ice-builder-gradle:Gradle插件可自动将Slice文件编译为Java

    ice-builder-gradle:Gradle插件可自动将Slice文件编译为Java

    Python:slice与indices的用法

     &gt;&gt;&gt;s=slice(2,3)  &gt;&gt;&gt;e[s]  [2]  slice的区间左闭右开[)  &gt;&gt;&gt;s  slice(2,3,None)  slice([strar,]stop[,step]),start缺少时就是0 indices:  eg:  &gt;&gt;&gt;print(s.indices(100))  (2,3,1)  &gt;&gt;&gt;print(s....

    x264_win32_支持多线程_slice大小控制

    2009年的一个x264的vfw版本,开源x264vfw版本已经不更新了,这里加入的多线程支持,slice大小控制在1000字节左右(这样打RTP包方便) 1c61eab4aef4.rar:原始当到的x264版本 win32_pthreads.2.rar:win32下的pthread...

    Zeroc ICE中间件slice2java的ant脚本(v1u0_0)

    NULL 博文链接:https://zhaoningbo.iteye.com/blog/1135564

    slice:slice包对Go slices进行排序

    片 这个软件包是Go 1.8的sort.Slice在将其添加到标准库之前先进行sort.Slice 。 不推荐使用:任何新代码都应改用标准库:

    slice2qt ice3.5.1 qt5.30版本

    qt使用ice时需要的代码转换工具。之前网上的版本最多支持到qt4.3,本版本支持qt5.3.0 ice3.5.1,应该是目前最新的版本。修改和增加的功能是手动修改的,并不一定适用所有项目,需要根据具体情况修改部分代码。

    Slice-docs:Slice项目的文档

    切片文档 Slice项目的文档 执照 Source Foundry Authors的分已获得许可

    slice-firmware:Slice的BCM270x固件相关资料

    切片固件Slice的BCM270x固件相关资料固件d-blob.bin Slice需要在FAT(引导)分区的根目录上具有正确的dt-blob.bin,才能正确设置初始引脚状态和时钟。 使用compile.sh脚本从slice-dt-blob.dts生成所需的dt-blob.bin

    Ice 分布式程序设计

    第 2 章 Ice 综述 第 3 章 Hello World 应用 第 4 章 Slice 语言 第 5 章 一个简单文件系统的 Slice 定义 第 6 章 客户端的 Slice-to-C++ 映射 第 7 章开发 C++ 文件系统客户 第 8 章 客户端的 Slice-to-Java 映射 ...

    slice函数的用法 之不错的应用

    代码如下:slice函数的用法:slice(a, b) 截取 数组 a 到 b 之间的元素组成新数组 截取到的元素为 a, a+1, …, b-1 删除数组中元素a到元素b的方法是: 合并元素a之前的元素与元素b起的元素; function...

Global site tag (gtag.js) - Google Analytics