一、ICE簡介:
1、ICE是什么?
ICE是ZEROC的開源通信協議產品,它的全稱是:The Internet Communications Engine,翻譯為中文是互聯網通信引擎,是一個面向對象的中間件,使我們能夠以最小的代價構建分布式應用程序。ICE使我們專注於應用邏輯的開發,它來處理所有底層的網絡接口編程,這樣我們就不用去考慮這樣的細節:打開網絡連接、網絡數據傳輸的序列化與反序列化、連接失敗的嘗試次數等。
2、為什么會有ICE?
ICE是分布式應用的一種比較好的解決方案,雖然現在也有一些比較流行的分布式應用解決方案,如微軟的.NET(以及原來的DCOM)、CORBA及WEB SERVICE等,但是這些面向對象的中間件都存在一些不足:
.NET是微軟產品,只面向WINDOWS系統,而實際的情況是在當前的網絡環境下,不同的計算機會運行不同的系統,如LINUX上面就不可能使用.NET;
CORBA雖然在統一標准方面做了很多的工作,但是不同的供應商實現之間還是缺乏互操作性,並且目前還沒有一家供應商可以針對所有的異種環境提供所有的實現支持,且CORBA的實現比較復雜,學習及實施的成本都會比較高;
WEB SERVICE最要命的缺點就是他的性能問題,對於要求比較高的行業是很少會考慮WEB SERVICE的。
ICE的產生就是源於.NET、CORBA及WEB SERVICE這些中間件的不足,它可以支持不同的系統,如WINDOWS、LINUX等,也可以支持在多種開發語言上使用,如C++、C、JAVA、RUBY、PYTHON、VB等,服務端可以是上面提到的任何一種語言實現的,客戶端也可以根據自己的實際情況選擇不同的語言實現,如服務端采用C語言實現,而客戶端采用JAVA語言實現,底層的通訊邏輯通過ICE的封裝實現,我們只需要關注業務邏輯。
3、ICE是如何工作的?
Ice 是一種面向對象的中間件平台,這意味着 Ice為構建面向對象的客戶-服務器應用提供了工具、API 和庫支持。要與Ice持有的對象進行通信,客戶端必須持有這個對象的代理(與CORBA的引用是相同的意思),這里的代理指的是這個對象的實例,ICE在運行時會定位到這個對象,然后尋找或激活它,再把In參數傳給遠程對象,再通過Out參數獲取返回結果。
這里提到的代理又分為直接代理和間接代理,直接代理其內部保存有某個對象的標識,以及它的服務器的運行地址;間接代理指的是其內部保存有某個對象的標識,以及對象適配器名(object adapter name),間接代理沒有包含尋址信息,為了正確地定位服務器,客戶端在運行時會使用代理內部的對象適配器名,將其傳給某個定位器服務,比如IcePack服務,然后,定位器會把適配器名當作關鍵字,在含有服務器地址的表中進行查找,把當前的服務器地址返回給客戶,客戶端 run time現在知道了怎樣聯系服務器,就會像平常一樣分派 (dispatch)客戶請求。
ICE可以保證在任何的網絡環境或者操作系統下,成功的調用只有一次,它在運行時會盡力的定位到遠程服務器,在連接失敗的情況下會做嘗試性重復性連接,確實連不上的情況會給用戶以提示。
客戶端在調用服務端的方法時,可以采取同步或異步的方式實現,同步調用就相當於調用自己本地的方法一樣,其它行為會被阻塞;異步調用是非常有用的調用方式,如服務端需要准備的數據來自於其它異步接口,這個時候客戶端就不需要等待,待服務端數據准備充份后,以消息的方式通知客戶端,服務端就可以去干其它的事情了,而客戶端也可以到服務端獲取數據了。
4、ICE調用模式
ICE采用的網絡協議有TCP、UDP以及SSL三 種,不同於WebService,ICE在調用模式上有好幾種選擇方案,並且每種方案正對不同的網絡協議的特性做了相應的選擇。
Oneway(單向調用):客戶端只需將調用注冊到本地傳輸緩沖區(Local Transport Buffers)后就立即返回,不會等待調用結果的返回,不對調用結果負責。
Twoway(雙向調用):最通用的模式,同步方法調用模式,只能用TCP或SSL協議。
Datagram(數據報):類似於Oneway調用,不同的是 Datagram調用只能采用UDP協議而且只能調用無返回值和無輸出參數的方法。
BatchOneway(批量單向調用):先將調用存 在調用緩沖區里面,到達一定限額后自動批量發送所有請求(也可手動刷除緩沖區)。
BatchDatagram(批量數據報):與上類似。
不同的調用模式其實對應着不動的業務,對於大部分的有返回值的或需要實時響應的方法,我們可能都采用Twoway方式調用,對於一些無需返回值或 者不依賴返回值的業務,我們可以用Oneway或者BatchOneway方式,例如消息通知;剩下的Datagram和BatchDatagram方式 一般用在無返回值且不做可靠性檢查的業務上,例如日志。
5、客戶端與服務端的結構
這個圖示顯示了使用ICE做為中間件平台,客戶端及服務端的應用都是由應用代碼及ICE的庫代碼混合組成的。
客戶應用及服務器應用分別對應用的是客戶端與服務端。
代理是根據SLICE定義的ice文件實現,它提供了一個向下調用的接口,提供了數據的序列化與反序化。
ICE的核心部份,提供了客戶端與服務端的網絡連接等核心通信功能,以及其它的網絡通信功能的實現及可能的問題的處理,讓我們在編寫應用代碼的時候不必要去關注這一塊,而專注於應用功能的實現。
二、ICE的安裝:
第一步,基於Windows下的安裝,所以下載windows版的Ice,官網最新版本是Ice3.4.2:
http://www.zeroc.com/download/Ice/3.4/Ice-3.4.2.msi
第二步,安裝Ice:
常規安裝即可,可以選擇安裝目錄,本次安裝是在D:\Ice
第三步,設置Ice的環境變量:
主要有環境變量需要設置:path、classpath、ICE_HOME
例如:
path:D:\Ice\bin;
classpath:D:\Ice\lib\Ice.jar;D:\Ice\lib\Freeze.jar;D:\Ice\lib\db.jar;
ICE_HOME:D:\Ice
第四步,檢驗:
在命令行中輸入:icegridnode --version
如果現實當前安裝的ice版本號,那么就說明安裝成功。
三、C++示例:
1、服務端:
a、添加一個名為Client的win32控制台應用程序的空白項目。
b、在屬性頁配置屬性->C/C++->常規->附加包含目錄加入$(ICE_HOME)\include;
c、在屬性頁配置屬性->鏈接器->常規->附加依賴項加入$(ICE_HOME)\lib;
d、在屬性頁配置屬性->鏈接器->輸入->附加依賴項加入加入iced.lib和iceutild.lib,也可以直接用$(ICE_HOME)\lib。但是這一步以上兩種加入都會出錯,錯誤為:LINK : fatal error LNK1104: 無法打開文件“C :\Program.obj”;所以最好是在工程里直接將那兩個庫添加進工程來。e、新增一個Caculator.ice文件。用記事本來寫即可以:
module MCal
{
//定義ICE接口,映射為C++里同名的一個類(純虛類,因此不能實例化,必須繼承並重載類中的 相應方法)
interface Cal
{
//定義接口里的操作,映射為C++里同名的一個純虛擬方法
int add(int num1,int num2);
int sub(int num1,int num2);
};
};
f、編譯Caculator.ice會生成Caculator.h 和Cacultor.cpp兩個文件。 編譯方法一:打開cmd,輸入slice2cpp Caculator.ice的路徑 ,如slice2cpp D:\TestIce\TestIce\ Caculator.ice。或許在你建立的工程中找不到這兩個文件,搜尋一下,看看在哪,然后將這兩個文件 放在Caculator.ice的目錄下。
g、Caculator.ice編譯成功后,建立服務器端CaculatorServer.cpp,type.h
type.h文件:
#ifndef _TYPE_H
#define _TYPE_H
#pragma once
#include "Calculate.h"
using namespace std;
using namespace MCal;
class CalI:public Cal
{
public:
CalI();
~CalI();
virtual int add(int num1,int num2,const Ice::Current&);
virtual int sub(int num1,int num2,const Ice::Current&);
private:
int num1d;
int num2d;
};
#endif
CaculatorServer.cpp文件:
// **********************************************************************
// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
// **********************************************************************
// Ice version 3.4.2
// <auto-generated>
// Generated from file `Calculate.ice'
// Warning: do not edit this file.
// </auto-generated>
#include "Calculate.h"
#include <Ice/LocalException.h>
#include <Ice/ObjectFactory.h>
#include <Ice/BasicStream.h>
#include <IceUtil/Iterator.h>
#ifndef ICE_IGNORE_VERSION
# if ICE_INT_VERSION / 100 != 304
# error Ice version mismatch!
# endif
# if ICE_INT_VERSION % 100 > 50
# error Beta header file detected
# endif
# if ICE_INT_VERSION % 100 < 2
# error Ice patch level mismatch!
# endif
#endif
static const ::std::string __MCal__Cal__add_name = "add";
static const ::std::string __MCal__Cal__sub_name = "sub";
::Ice::Object* IceInternal::upCast(::MCal::Cal* p) { return p; }
::IceProxy::Ice::Object* IceInternal::upCast(::IceProxy::MCal::Cal* p) { return p; }
voidMCal::__read(::IceInternal::BasicStream* __is, ::MCal::CalPrx& v)
{
::Ice::ObjectPrx proxy;
__is->read(proxy);
if(!proxy)
{
v = 0;
}
else
{
v = new ::IceProxy::MCal::Cal;
v->__copyFrom(proxy);
}
}
::Ice::IntIceProxy::MCal::Cal::add(::Ice::Int num1, ::Ice::Int num2, const ::Ice::Context* __ctx)
{
int __cnt = 0;
while(true)
{
::IceInternal::Handle< ::IceDelegate::Ice::Object> __delBase;
try
{
__checkTwowayOnly(__MCal__Cal__add_name);
__delBase = __getDelegate(false);
::IceDelegate::MCal::Cal* __del = dynamic_cast< ::IceDelegate::MCal::Cal*>(__delBase.get());
return __del->add(num1, num2, __ctx);
}
catch(const ::IceInternal::LocalExceptionWrapper& __ex)
{
__handleExceptionWrapper(__delBase, __ex);
}
catch(const ::Ice::LocalException& __ex)
{
__handleException(__delBase, __ex, true, __cnt);
}
}
}
::Ice::AsyncResultPtrIceProxy::MCal::Cal::begin_add(::Ice::Int num1, ::Ice::Int num2, const ::Ice::Context* __ctx, const ::IceInternal::CallbackBasePtr& __del, const ::Ice::LocalObjectPtr& __cookie)
{
__checkAsyncTwowayOnly(__MCal__Cal__add_name);
::IceInternal::OutgoingAsyncPtr __result = new ::IceInternal::OutgoingAsync(this, __MCal__Cal__add_name, __del, __cookie);
try
{
__result->__prepare(__MCal__Cal__add_name, ::Ice::Normal, __ctx);
::IceInternal::BasicStream* __os = __result->__getOs();
__os->write(num1);
__os->write(num2);
__os->endWriteEncaps();
__result->__send(true);
}
catch(const ::Ice::LocalException& __ex)
{
__result->__exceptionAsync(__ex);
}
return __result;
}
::Ice::IntIceProxy::MCal::Cal::end_add(const ::Ice::AsyncResultPtr& __result)
{
::Ice::AsyncResult::__check(__result, this, __MCal__Cal__add_name);
::Ice::Int __ret;
if(!__result->__wait())
{
try
{
__result->__throwUserException();
}
catch(const ::Ice::UserException& __ex)
{
throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name());
}
}
::IceInternal::BasicStream* __is = __result->__getIs();
__is->startReadEncaps();
__is->read(__ret);
__is->endReadEncaps();
return __ret;
}
::Ice::IntIceProxy::MCal::Cal::sub(::Ice::Int num1, ::Ice::Int num2, const ::Ice::Context* __ctx)
{
int __cnt = 0;
while(true)
{
::IceInternal::Handle< ::IceDelegate::Ice::Object> __delBase;
try
{
__checkTwowayOnly(__MCal__Cal__sub_name);
__delBase = __getDelegate(false);
::IceDelegate::MCal::Cal* __del = dynamic_cast< ::IceDelegate::MCal::Cal*>(__delBase.get());
return __del->sub(num1, num2, __ctx);
}
catch(const ::IceInternal::LocalExceptionWrapper& __ex)
{
__handleExceptionWrapper(__delBase, __ex);
}
catch(const ::Ice::LocalException& __ex)
{
__handleException(__delBase, __ex, true, __cnt);
}
}
}
::Ice::AsyncResultPtrIceProxy::MCal::Cal::begin_sub(::Ice::Int num1, ::Ice::Int num2, const ::Ice::Context* __ctx, const ::IceInternal::CallbackBasePtr& __del, const ::Ice::LocalObjectPtr& __cookie)
{
__checkAsyncTwowayOnly(__MCal__Cal__sub_name);
::IceInternal::OutgoingAsyncPtr __result = new ::IceInternal::OutgoingAsync(this, __MCal__Cal__sub_name, __del, __cookie);
try
{
__result->__prepare(__MCal__Cal__sub_name, ::Ice::Normal, __ctx);
::IceInternal::BasicStream* __os = __result->__getOs();
__os->write(num1);
__os->write(num2);
__os->endWriteEncaps();
__result->__send(true);
}
catch(const ::Ice::LocalException& __ex)
{
__result->__exceptionAsync(__ex);
}
return __result;
}
::Ice::IntIceProxy::MCal::Cal::end_sub(const ::Ice::AsyncResultPtr& __result)
{
::Ice::AsyncResult::__check(__result, this, __MCal__Cal__sub_name);
::Ice::Int __ret;
if(!__result->__wait())
{
try
{
__result->__throwUserException();
}
catch(const ::Ice::UserException& __ex)
{
throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name());
}
}
::IceInternal::BasicStream* __is = __result->__getIs();
__is->startReadEncaps();
__is->read(__ret);
__is->endReadEncaps();
return __ret;
}
const ::std::string&IceProxy::MCal::Cal::ice_staticId()
{
return ::MCal::Cal::ice_staticId();
}
::IceInternal::Handle< ::IceDelegateM::Ice::Object>IceProxy::MCal::Cal::__createDelegateM()
{
return ::IceInternal::Handle< ::IceDelegateM::Ice::Object>(new ::IceDelegateM::MCal::Cal);
}
::IceInternal::Handle< ::IceDelegateD::Ice::Object>IceProxy::MCal::Cal::__createDelegateD()
{
return ::IceInternal::Handle< ::IceDelegateD::Ice::Object>(new ::IceDelegateD::MCal::Cal);
}
::IceProxy::Ice::Object*IceProxy::MCal::Cal::__newInstance() const
{
return new Cal;
}
::Ice::IntIceDelegateM::MCal::Cal::add(::Ice::Int num1, ::Ice::Int num2, const ::Ice::Context* __context)
{
::IceInternal::Outgoing __og(__handler.get(), __MCal__Cal__add_name, ::Ice::Normal, __context);
try
{
::IceInternal::BasicStream* __os = __og.os();
__os->write(num1);
__os->write(num2);
}
catch(const ::Ice::LocalException& __ex)
{
__og.abort(__ex);
}
bool __ok = __og.invoke();
::Ice::Int __ret;
try
{
if(!__ok)
{
try
{
__og.throwUserException();
}
catch(const ::Ice::UserException& __ex)
{
::Ice::UnknownUserException __uue(__FILE__, __LINE__, __ex.ice_name());
throw __uue;
}
}
::IceInternal::BasicStream* __is = __og.is();
__is->startReadEncaps();
__is->read(__ret);
__is->endReadEncaps();
return __ret;
}
catch(const ::Ice::LocalException& __ex)
{
throw ::IceInternal::LocalExceptionWrapper(__ex, false);
}
}
::Ice::IntIceDelegateM::MCal::Cal::sub(::Ice::Int num1, ::Ice::Int num2, const ::Ice::Context* __context)
{
::IceInternal::Outgoing __og(__handler.get(), __MCal__Cal__sub_name, ::Ice::Normal, __context);
try
{
::IceInternal::BasicStream* __os = __og.os();
__os->write(num1);
__os->write(num2);
}
catch(const ::Ice::LocalException& __ex)
{
__og.abort(__ex);
}
bool __ok = __og.invoke();
::Ice::Int __ret;
try
{
if(!__ok)
{
try
{
__og.throwUserException();
}
catch(const ::Ice::UserException& __ex)
{
::Ice::UnknownUserException __uue(__FILE__, __LINE__, __ex.ice_name());
throw __uue;
}
}
::IceInternal::BasicStream* __is = __og.is();
__is->startReadEncaps();
__is->read(__ret);
__is->endReadEncaps();
return __ret;
}
catch(const ::Ice::LocalException& __ex)
{
throw ::IceInternal::LocalExceptionWrapper(__ex, false);
}
}
::Ice::IntIceDelegateD::MCal::Cal::add(::Ice::Int num1, ::Ice::Int num2, const ::Ice::Context* __context)
{
class _DirectI : public ::IceInternal::Direct
{
public:
_DirectI(::Ice::Int& __result, ::Ice::Int num1, ::Ice::Int num2, const ::Ice::Current& __current) :
::IceInternal::Direct(__current),
_result(__result),
_m_num1(num1),
_m_num2(num2)
{
}
virtual ::Ice::DispatchStatus
run(::Ice::Object* object)
{
::MCal::Cal* servant = dynamic_cast< ::MCal::Cal*>(object);
if(!servant)
{
throw ::Ice::OperationNotExistException(__FILE__, __LINE__, _current.id, _current.facet, _current.operation);
}
_result = servant->add(_m_num1, _m_num2, _current);
return ::Ice::DispatchOK;
}
private:
::Ice::Int& _result;
::Ice::Int _m_num1;
::Ice::Int _m_num2;
};
::Ice::Current __current;
__initCurrent(__current, __MCal__Cal__add_name, ::Ice::Normal, __context);
::Ice::Int __result;
try
{
_DirectI __direct(__result, num1, num2, __current);
try
{
__direct.servant()->__collocDispatch(__direct);
}
catch(...)
{
__direct.destroy();
throw;
}
__direct.destroy();
}
catch(const ::Ice::SystemException&)
{
throw;
}
catch(const ::IceInternal::LocalExceptionWrapper&)
{
throw;
}
catch(const ::std::exception& __ex)
{
::IceInternal::LocalExceptionWrapper::throwWrapper(__ex);
}
catch(...)
{
throw ::IceInternal::LocalExceptionWrapper(::Ice::UnknownException(__FILE__, __LINE__, "unknown c++ exception"), false);
}
return __result;
}
::Ice::IntIceDelegateD::MCal::Cal::sub(::Ice::Int num1, ::Ice::Int num2, const ::Ice::Context* __context)
{
class _DirectI : public ::IceInternal::Direct
{
public:
_DirectI(::Ice::Int& __result, ::Ice::Int num1, ::Ice::Int num2, const ::Ice::Current& __current) :
::IceInternal::Direct(__current),
_result(__result),
_m_num1(num1),
_m_num2(num2)
{
}
virtual ::Ice::DispatchStatus
run(::Ice::Object* object)
{
::MCal::Cal* servant = dynamic_cast< ::MCal::Cal*>(object);
if(!servant)
{
throw ::Ice::OperationNotExistException(__FILE__, __LINE__, _current.id, _current.facet, _current.operation);
}
_result = servant->sub(_m_num1, _m_num2, _current);
return ::Ice::DispatchOK;
}
private:
::Ice::Int& _result;
::Ice::Int _m_num1;
::Ice::Int _m_num2;
};
::Ice::Current __current;
__initCurrent(__current, __MCal__Cal__sub_name, ::Ice::Normal, __context);
::Ice::Int __result;
try
{
_DirectI __direct(__result, num1, num2, __current);
try
{
__direct.servant()->__collocDispatch(__direct);
}
catch(...)
{
__direct.destroy();
throw;
}
__direct.destroy();
}
catch(const ::Ice::SystemException&)
{
throw;
}
catch(const ::IceInternal::LocalExceptionWrapper&)
{
throw;
}
catch(const ::std::exception& __ex)
{
::IceInternal::LocalExceptionWrapper::throwWrapper(__ex);
}
catch(...)
{
throw ::IceInternal::LocalExceptionWrapper(::Ice::UnknownException(__FILE__, __LINE__, "unknown c++ exception"), false);
}
return __result;
}
::Ice::ObjectPtrMCal::Cal::ice_clone() const
{
throw ::Ice::CloneNotImplementedException(__FILE__, __LINE__);
return 0; // to avoid a warning with some compilers
}
static const ::std::string __MCal__Cal_ids[2] =
{
"::Ice::Object",
"::MCal::Cal"
};
boolMCal::Cal::ice_isA(const ::std::string& _s, const ::Ice::Current&) const
{
return ::std::binary_search(__MCal__Cal_ids, __MCal__Cal_ids + 2, _s);
}
::std::vector< ::std::string>MCal::Cal::ice_ids(const ::Ice::Current&) const
{
return ::std::vector< ::std::string>(&__MCal__Cal_ids[0], &__MCal__Cal_ids[2]);
}
const ::std::string&MCal::Cal::ice_id(const ::Ice::Current&) const
{
return __MCal__Cal_ids[1];
}
const ::std::string&MCal::Cal::ice_staticId()
{
return __MCal__Cal_ids[1];
}
::Ice::DispatchStatusMCal::Cal::___add(::IceInternal::Incoming& __inS, const ::Ice::Current& __current)
{
__checkMode(::Ice::Normal, __current.mode);
::IceInternal::BasicStream* __is = __inS.is();
__is->startReadEncaps();
::Ice::Int num1;
::Ice::Int num2;
__is->read(num1);
__is->read(num2);
__is->endReadEncaps();
::IceInternal::BasicStream* __os = __inS.os();
::Ice::Int __ret = add(num1, num2, __current);
__os->write(__ret);
return ::Ice::DispatchOK;
}
::Ice::DispatchStatusMCal::Cal::___sub(::IceInternal::Incoming& __inS, const ::Ice::Current& __current)
{
__checkMode(::Ice::Normal, __current.mode);
::IceInternal::BasicStream* __is = __inS.is();
__is->startReadEncaps();
::Ice::Int num1;
::Ice::Int num2;
__is->read(num1);
__is->read(num2);
__is->endReadEncaps();
::IceInternal::BasicStream* __os = __inS.os();
::Ice::Int __ret = sub(num1, num2, __current);
__os->write(__ret);
return ::Ice::DispatchOK;
}
static ::std::string __MCal__Cal_all[] =
{
"add",
"ice_id",
"ice_ids",
"ice_isA",
"ice_ping",
"sub"
};
::Ice::DispatchStatusMCal::Cal::__dispatch(::IceInternal::Incoming& in, const ::Ice::Current& current)
{
::std::pair< ::std::string*, ::std::string*> r = ::std::equal_range(__MCal__Cal_all, __MCal__Cal_all + 6, current.operation);
if(r.first == r.second)
{
throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation);
}
switch(r.first - __MCal__Cal_all)
{
case 0:
{
return ___add(in, current);
}
case 1:
{
return ___ice_id(in, current);
}
case 2:
{
return ___ice_ids(in, current);
}
case 3:
{
return ___ice_isA(in, current);
}
case 4:
{
return ___ice_ping(in, current);
}
case 5:
{
return ___sub(in, current);
}
}
assert(false);
throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation);
}
voidMCal::Cal::__write(::IceInternal::BasicStream* __os) const
{
__os->writeTypeId(ice_staticId());
__os->startWriteSlice();
__os->endWriteSlice();
#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug
Object::__write(__os);
#else
::Ice::Object::__write(__os);
#endif
}
voidMCal::Cal::__read(::IceInternal::BasicStream* __is, bool __rid)
{
if(__rid)
{
::std::string myId;
__is->readTypeId(myId);
}
__is->startReadSlice();
__is->endReadSlice();
#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6 compiler bug
Object::__read(__is, true);
#else
::Ice::Object::__read(__is, true);
#endif
}
// COMPILERFIX: Stream API is not supported with VC++ 6
#if !defined(_MSC_VER) || (_MSC_VER >= 1300)
voidMCal::Cal::__write(const ::Ice::OutputStreamPtr&) const
{
Ice::MarshalException ex(__FILE__, __LINE__);
ex.reason = "type MCal::Cal was not generated with stream support";
throw ex;
}
voidMCal::Cal::__read(const ::Ice::InputStreamPtr&, bool)
{
Ice::MarshalException ex(__FILE__, __LINE__);
ex.reason = "type MCal::Cal was not generated with stream support";
throw ex;
}
#endif
void MCal::__patch__CalPtr(void* __addr, ::Ice::ObjectPtr& v)
{
::MCal::CalPtr* p = static_cast< ::MCal::CalPtr*>(__addr);
assert(p);
*p = ::MCal::CalPtr::dynamicCast(v);
if(v && !*p)
{
IceInternal::Ex::throwUOE(::MCal::Cal::ice_staticId(), v->ice_id());
}
}
編譯成功,如果有很多錯誤,可能是沒有加入庫文件iced.lib和iceutild.lib 如果成功,服務器端建立成功。
h、客戶端程序main.cpp.
重新建立工程,Client,建立客戶端CalculatorClient.cpp
將生成的Calculator.h 和Calculator.cpp加入Client工程中,然后建立CalculatorClient.cpp
#include <Ice/Ice.h>
#include <Ice/Application.h>
#include "Calculator.h"
#include<iostream>
using namespace std;
using namespace MCal;
//#define RC_List "/home/tester/Key_Checking/ATT_RC/RMT_B109P_EU_Set.txt"
//#define RC_Data "/home/tester/Key_Checking/ATT_RC/RMT_B109P_EU_Set.dat"
class MyApp : virtual public Ice::Application
{
public:
virtual int run(int,char*[]);
};
int MyApp::run(int,char*[])
{
Ice::ObjectPrx base = communicator()->stringToProxy("Cal:default -p 10000");
CalPrx calculator = CalPrx::checkedCast(base);
if(!calculator)
throw "Invalid proxy!";
cout<<calculator->add(1,2)<<endl;
cout<<calculator->sub(56,12)<<endl;
//Calc->Close();
return 0;
}
int main(int argc,char* argv[])
{
MyApp app;
return app.main(argc,argv);
}
至此,完成....!
附件,本demo示例源碼見:http://download.csdn.net/detail/wqc19920906/9405766