ICE阅读笔记

Chapter 3
A Hello World Application

------------------------------------

3.1Chapter Overview
In this chapter, we will see how to create a very simple client–server application in
both C++ and Java. The application enables remote printing: a client sends the text
to be printed to a server, which in turn sends that text to a printer.
For simplicity (and because we do not want to concern ourselves with the idiosyncrasies
of print spoolers for various platforms), our printer will simply print to
a terminal instead of a real printer. This is no great loss: the purpose of the exercise
is to show how a client can communicate with a server; once the thread of
control has reached the server application code, that code can of course do
anything it likes (including sending the text to a real printer). How to do this is
independent of Ice and therefore not relevant here.
Note that much of the detail of the source code will remain unexplained for
now. The intent is to show you how to get started and give you a feel for what the
development environment looks like; we will provide all the detail throughout the
remainder of this book.
3.2Writing a Slice Definition
The first step in writing any Ice application is to write a Slice definition containing
the interfaces that are used by the application. For our minimal printing application,
we write the following Slice definition:
interface Printer
{
void printString(string s);
};
We save this text in a file called Printer.ice.
Our Slice definition contains a single interface called Printer. For now, the
interface is very simple and provides only a single operation, called printString.
The printString operation accepts a string as its sole input parameter; the text of
that string is what appears on the (possibly remote) printer.
3.3Writing an Ice Application with C++
This section shows how to create an Ice application with C++. The equivalent Java
version is shown in Section 3.4 on page 42.
Compiling a Slice Definition for C++
The first step in creating our C++ application is to compile our Slice definition to
generate C++ proxies and skeletons. Under UNIX, you can compile the definition
as follows:
$ slice2cpp Printer.ice
The slice2cpp compiler produces two C++ source files from this definition,
Printer.h and Printer.cpp.
• Printer.h
The Printer.h header file contains C++ type definitions that correspond to
the Slice definitions for our Printer interface. This header file must be
included in both the client and the server source code.
• Printer.cpp
The Printer.cpp file contains the source code for our Printer interface.
The generated source contains type-specific run-time support for both clients
and servers. For example, it contains code that marshals parameter data (the
string passed to the printString operation) on the client side and unmarshals
that data on the server side.
The Printer.cpp file must be compiled and linked into both client and
server.
Writing and Compiling a Server
The source code for the server takes only a few lines and is shown in full here:
#include <Ice/Ice.h>
#include <Printer.h>
using namespace std;
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)
ic->destroy();
return status;
}
There appears to be a lot of code here for something as simple as a server that just
prints a string. Do not be concerned by this: most of the preceding code is boiler
plate that never changes. For this very simple server, the code is dominated by this
boiler plate.
Every Slice source file starts with an include directive for Ice.h, which
contains the definitions for the Ice run time. We also include Printer.h, which
was generated by the Slice compiler and contains the C++ definitions for our
printer interface, and we import the contents of the std namespace for brevity in
the code that follows:
#include <Ice/Ice.h>
#include <Printer.h>
using namespace std;
Our server implements a single printer servant, of type PrinterI. Looking at
the generated code in Printer.h, we find the following (tidied up a little to get
rid of irrelevant detail):
class Printer : virtual public Ice::Object {
public:
virtual void printString(const std::string &,
const Ice::Current & = Ice::Current()
) = 0;
};
The Printer skeleton class definition is generated by the Slice compiler. (Note
that the printString method is pure virtual so the skeleton class cannot be
instantiated.) Our servant class inherits from the skeleton class to provide an
implementation of the pure virtual printString method. (By convention, we
use an I-suffix to indicate that the class implements an interface.)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值