牵牛散步
仗剑走天涯

准备工作

按照某人的说法:跨平台的C++网络编程ICE才是王道。于是,我学习ICE。

ICE才出来两年,是“一种现代的面向对象中间件,可用于替代像CORBA或COM/DCOM/COM+这样的中间件。在易于学习的同时,它为各种有着苛刻的技术要求的应用提供了强大的网络基础设施。”Ice 3.0 已实现对C++, Java, Python, PHP, C# 及 Visual Basic 的支持。

这里我就不多说了,大家可以参考这篇文章:《反叛之冰:Internet Communications Engine 》。大家可以下载的ICE的官方参考手册,有中文版,不过是1.3.0版, 英文的是3.0版。

ICE是开源的,大家可以从源代码开始编译,不过较复杂,幸好有binary版本,比如我就是下载的VS2003.NET的安装包。安装完成之后按照安装目录下的Readme对IDE进行一下配置,比如VC7.1就是把ice的include加入VC7.1的引用文件目录,把ice的lib目录加入VC7.1的库文件目录。然后再把安装目录下的bin文件夹添加到系统的环境变量Path中,最后,把bin文件夹下的所有DLL文件都Copy到Windows安装目录下的System32文件夹下(win98下是System文件夹?)。

ICE自定义了一种SLICE语言,目的是定义接口,作用主要应该是保持对象调用或者数据传输时的语言无关性。

开发一个ICE应用程序可以分为三步:

  1. 写一个Slice定义, 并且编译它

  2. 写服务端, 并编译它

  3. 写客户端, 并编译它

OK,写一个小程序,实现客户发送要打印的文本给服务器,再由服务器把文本发给打印机(这里我们用屏幕显示替代),这里对代码解读请见下一章,这里不多说。

  1. 写一个Slice定义, 并且编译它:

    文件Printer.ice. 

    module Demo {
    interface Printer {
    	void printString(string s);
    	};
    };
    

    这个文件很简单, 但需要注意, 在区分大小写的系统上, 扩展名一定是小写.

    编译也很简单,首先确认你已将你的bin目录加到系统的环境变量Path中.然后把上面这个片断保存成Printer.ice, 最后执行slice2cpp Printer.ice, 执行后的结果应该是自动生成了printer.h和printer.cpp.

  2. 写服务端, 并编译它

    文件server.cpp. 

    #include <Ice/Ice.h> 
    #include "../print.h"
    using namespace std;
    using namespace Demo;
    class PrinterI : public Printer {
    public:
    	virtual void printString(const string& s,const Ice::Current&);
    };
    void PrinterI::printString(const string& s, const Ice::Current&)
    {
    	cout << s << endl;
    }
    int  main(int argc, char* argv[])
    {
    	int status = 0;
    	Ice::CommunicatorPtr ic;
    	try {
    		ic = Ice::initialize(argc, argv);
    		Ice::ObjectAdapterPtr adapter
    			= ic->createObjectAdapterWithEndpoints(
    			"SimplePrinterAdapter", "default -p 10000");
    		Ice::ObjectPtr object = new PrinterI;
    		adapter->add(object,
    			Ice::stringToIdentity("SimplePrinter"));
    		adapter->activate();
    		ic->waitForShutdown();
    	} catch (const Ice::Exception& e) {
    			cerr << e << endl;
    		status = 1;
    	} catch (const char* msg) {
    		cerr << msg << endl;
    		status = 1;
    	}
    	if (ic) {
    		try {
    			ic->destroy();
    		} catch (const Ice::Exception& e) {
    			cerr << e << endl;
    			status = 1;
    		}
    	}
    	return status;
    }
    

    以VS2003的配置为例

    1. 把ice的include加入VC7.1的引用文件目录,把ice的lib目录加入VC7.1的库文件目录。然后再把安装目录下的bin文件夹添加到系统的环境变量Path中,最后,把bin文件夹下的所有DLL文件都Copy到Windows安装目录下的System32文件夹下(win98下是System文件夹?)(当然,DLL文件的问题也可以通过修改环境变量来解决,不过是那个变量呢?Who can tell me?)

    2. 新建一个C++的Win32的命令台控制程序,并且设置为空项目, 把server.cpp, printer.cpp和printer.h加入这个项目(printer.cpp和printer.h放在项目的目录的外一层目录)

    3. 项目-》属性-》C/C++ -》代码生成-》运行时库-》/MD(realse版)或/MDd(debug版)

      项目-》配置属性-》C/C++-》语言-》启用运行时类型信息/GR 开启

      设置:项目-》属性-》链接器-》输入-》加入iced.lib iceutild.lib,此处一定要把realse库和debug库分清, debug库后有个d

    4. 修改printer.cpp中的#include <printer.h>为#include "printer.h"

    5. OK,编译

  3. 写客户端,并编译它

    文件client.cpp. 

    #include <Ice/Ice.h>
    #include "..\print.h"
    using namespace std;
    using namespace Demo;
    int main(int argc, char* argv[])
    {
    	int status = 0;
    	Ice::CommunicatorPtr ic;
    	try {
    		ic = Ice::initialize(argc, argv);
    		Ice::ObjectPrx base = ic->stringToProxy(
    			"SimplePrinter:default -p 10000");
    		PrinterPrx printer = PrinterPrx::checkedCast(base);
    		if (!printer)
    			throw "Invalid proxy";
    		printer->printString("Hello World!");
    	} catch (const Ice::Exception& ex) {
    		cerr << ex << endl;
    		status = 1;
    	} catch (const char* msg) {
    		cerr << msg << endl;
    		status = 1;
    	}
    	if (ic)
    		ic->destroy();
    	return status;
    }
    

    添加一个新项目到当前解决方案,按照上面的方法,对client再一次进行设置。

    在解决方案管理器的解决方案上点击右键,选择批生成Debug版本,然到用资源管理器到两个解决方案的目录下的Debug文件夹中执行生产的可执行文件。先运行server.exe, 然后运行client.exe, 哈哈, 是不是在server.exe的窗口里出现了Hello World!(运行一次client.exe,出现一条)

 

文章源地址:http://enjoylanguage.sourceforge.net/%5Bxhtml_chunk_sourceForge%5D/ch02.html

posted on 2005-12-13 11:56 牵牛散步 阅读(3661) 评论(5)  编辑 收藏 引用 所属分类: ICE学习资料
Comments
  • # re: 转载:学习ICE 3.0--准备工作
    rwxybh
    Posted @ 2005-12-16 15:07
    1.上面的例子只能单机运行,真正远程调用的话要用-h host 参数
    2.不太明白文档中的一个说明:
    icegridadmin中有个object add 命令
    比如:object add "EncoderFactory@EncoderAdapter"
    问题是应该怎么使用这个命令
    它如何替代object的描述文件,命令既没有指定Application,也没有说明Node  回复  更多评论   
  • # re: 转载:学习ICE 3.0--准备工作
    牵牛散步
    Posted @ 2005-12-19 10:00
    object add "EncoderFactory@EncoderAdapter"

    呵.老兄.这里我还没看到呐...  回复  更多评论   
  • # re: 转载:学习ICE 3.0--准备工作
    橙子
    Posted @ 2006-04-21 09:08
    ICE和ACE有什么区别阿?  回复  更多评论   
  • # re: 转载:学习ICE 3.0--准备工作
    哈哈哈
    Posted @ 2006-08-04 16:08
    最后执行slice2cpp Printer.ice, 执行后的结果应该是自动生成了printer.h和printer.cpp

    为什么我生成的是Printer.h和Printer.cpp  回复  更多评论   
  • # re: 转载:学习ICE 3.0--准备工作
    深海之鱼
    Posted @ 2006-11-23 14:15
    @哈哈哈:因为作者写错了。
      回复  更多评论   

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理