??xml version="1.0" encoding="utf-8" standalone="yes"?>区久久AAA片69亚洲,91超碰碰碰碰久久久久久综合,精品久久综合1区2区3区激情 http://www.shnenglu.com/klsmlzm/category/558.html暂时?/description>zh-cnWed, 21 May 2008 08:36:45 GMTWed, 21 May 2008 08:36:45 GMT60LINUX下简单的~译和用动态链接库[compile .so use c++ in linux]http://www.shnenglu.com/klsmlzm/archive/2006/04/21/6026.html늉散步늉散步Fri, 21 Apr 2006 07:06:00 GMThttp://www.shnenglu.com/klsmlzm/archive/2006/04/21/6026.htmlhttp://www.shnenglu.com/klsmlzm/comments/6026.htmlhttp://www.shnenglu.com/klsmlzm/archive/2006/04/21/6026.html#Feedback0http://www.shnenglu.com/klsmlzm/comments/commentRss/6026.htmlhttp://www.shnenglu.com/klsmlzm/services/trackbacks/6026.html 对动态链接库的概念其实还很模p?自己的理解是:
把一些常用的代码,如函?cȝ,~译成一??即DLL(WINDOWS?或者SO(LINUX?文g,
然后供其它程序用时直接调用里面闭的函数即?实现的代码的重用,也节省了(jin)
盘I间(q点可能是次要的?.在WIDOWS下利用VC++可方便的生成DLL,在LINUX下则需要通过
各种~译命o(h)来实?对于像我q种菜鸟U程序员来说是个不小的挑(xi)?
下面用个单的例子来说明生成一?SO文g和如何用它:
1.我这有几个文?
ConfigMap.cpp ConfigMap.h (读配|文件类)GetWinState.cpp GetWinState.h(ICE接口文g,由SLICE生成) GetWinSysState.cpp GetWinSysState.h (q程接口实现文g)
SocDbInfo.cpp(装的一个类,用于调用ICE接口实现相关操作)
说明:此程序是Z(jin)获得q程L(WINDOWS)上一些系l信?比如:CPU占用?盘?sh)用情?数据
库连接状?内存?sh)用情况{?
我想利用q些文g生成动态链接库.SO,主要是调用SocDbInfo.cpp里的c?然后可以拿到L一个系l中(LINUX)ȝ.
2.开始编?$c++ -I. -I$ICE_HOME/include -c *.cpp
~译后生成连接文?我一直这样叫,可能不对?,即以.Ol尾?br />3.生成动态链接库:$c++ -shared -o (tng)libMyApp.so *.o -L$ICE_HOME/lib -lIce -lIceUtil
q样q成了(jin)libMyApp.so文g,x(chng)们所要的
4.使用动态链接库:
新徏两个文gDemo.cpp Demo.h(使用libMyApp.so提供的一些函?,
在Demo.h中声明了(jin)libMyApp.so中提供的函数和结构体,
Demo.h:代码如下:

struct MemoryInf
{
 (tng)int TotalMem;//×ÜÄÚ´æ´Q(mo)С
 (tng)int ValidMem;//HÉʹÓÃÄÚ´æ´Q(mo)С
 (tng)int VirtualMem;//ÐéÄâÄÚ´æ´Q(mo)С
};
struct DiskInf
{
 (tng)int TotalSpace;//Ó̔ÅÌ´Q(mo)С
 (tng)int FreeSpace;//ÊnÓàHÕä´Q(mo)С
};
struct DbInf
{
 (tng)int DbStat;//Êý¾ÝHâ×´ÌR:"0"uTʾÊý¾ÝHâ´ÔÚ¹ØuÕ×´ÌR,"1"uTʾÊý¾ÝHâÕýn´òHª,"2"uTʾÊý¾ÝHâ´ÔÚ¹ÒÆð×´ÌR
 (tng)int DbConnNum;//Êý¾ÝHâÁRÓÊý
};
bool Inital( char *ResHostIP);//õÊ䛵tÍtÐÅÆ÷
bool DesIceCom();//ÏúÙICEÍtÐÅÆ÷
MemoryInf GetMemInf();//µÃµÄÚ´æÐÅÏ
int GetCpuInf();//µÃµCPUÕÓÃÂÊ
DbInf GetDbStat();//µÃµÊý¾ÝHâÐÅÏ
DiskInf GetDiskStat();//µÃµÓ̔ÅÌÐÅÏ



?q是由于我的LINUX下不支持中文?是注释不用管?br />Demo.cpp:代码如下:
#include <string.h>
#include <iostream>
#include "Demo.h"


int main( int argc , char* argv[])
{

 (tng)MemoryInf mymem;
 (tng)DiskInf mydisk;
 (tng)DbInf mydb;
 (tng)I(yng)nital( argv[1]);
 (tng)mydisk = GetDiskStat();
 (tng)mymem = GetMemInf();
 (tng)mydb = GetDbStat();
 (tng)printf("disk total space:%d\n",mydisk.TotalSpace);
 (tng)printf("disk FreeSpace space:%d\n",mydisk.FreeSpace);
 (tng)printf("Memory TotalMem:%d\n",mymem.TotalMem);
 (tng)printf("ValidMem:%d\n",mymem.ValidMem);
 (tng)printf("VirtualMem:%d\n",mymem.VirtualMem);
 (tng)printf("DbConnNum:%d\n",mydb.DbConnNum);
 (tng)printf("DbStat:%d\n",mydb.DbStat);
 (tng)printf("cpu:%d\n",GetCpuInf());
 (tng)DesIceCom();
 (tng)return 1;
}


5.~译文g生成可执行程?
用以下命?
$c++ (tng)-lMyApp (tng)-o (tng)Demo (tng)Demo.cpp
说明:-lMyApp参数表示,用动态链接库libMyApp.so一赯行编?对了(jin)libMyApp.so最好放?usr/lib目录下哈
如不出意外刚?x)生成名为Demo的可执行文g



늉散步 2006-04-21 15:06 发表评论
]]>
转蝲:学习(fn)ICE 3.0--Slice语言http://www.shnenglu.com/klsmlzm/archive/2005/12/13/1712.html늉散步늉散步Tue, 13 Dec 2005 04:00:00 GMThttp://www.shnenglu.com/klsmlzm/archive/2005/12/13/1712.htmlhttp://www.shnenglu.com/klsmlzm/comments/1712.htmlhttp://www.shnenglu.com/klsmlzm/archive/2005/12/13/1712.html#Feedback0http://www.shnenglu.com/klsmlzm/comments/commentRss/1712.htmlhttp://www.shnenglu.com/klsmlzm/services/trackbacks/1712.html

Slice语言

首先Q请大家读ICE中文手册中的Slice语言一章?q一部分除了(jin)modelQ模块)(j)Q在 ICE 1.3中文手册中都有描q?

?nbsp;2.1. ice|络~程C意?服务器端和客L(fng)采用同种~程语言CQ+)

ice|络~程C意?服务器端和客L(fng)采用同种~程语言CQ+)

?nbsp;2.2. ice|络~程C意?服务器端和客L(fng)采用不同~程语言)

ice|络~程C意?服务器端和客L(fng)采用不同~程语言)

基础知识

含有Slice 定义的文件必M.ice 扩展名结,例如Q?Clock.ice是一个有效的文g名。编译器拒绝接受其他扩展名?

Slice 支持#ifndef?define?endifQ以?include 预处理指令。它们的使用方式有严格的限制Q你只能?ifndef?defineQ以?endif 指o(h)用于创徏双包括(double-includeQ块。例如:(x)

#ifndef _CLOCK_ICE
#define _CLOCK_ICE
// #include 文g here...
//定义 here...
#endif _CLOCK_ICE

我们强烈你在所有的Slice 定义中用双包括Qdouble-includeQ块Q所上)(j)Q防止多ơ包括同一文g?

#include 指o(h)只能出现在Slice 源文件的开_(d)也就是说Q它们必d现在其他所有Slice 定义的前面。此外,在?include 指o(h)Ӟ只允怋?lt;> 语法来指定文件名Q不能?"。例如:(x)

 #include <File1.ice> // OK
#include "File2.ice" // 不支?

你不能把q些预处理指令用于其他目的,也不能用其他的C++ 预处理指?Q比如用\ 字符来连接行、token _脓(chung)Q以?qing)宏展开Q等{)(j)?

在Slice 定义里,既可以用C 的、也可以使用C++ 的注释风|(x)

Slice 关键字必d写。例如, class 和dictionary 都是关键字,必须按照所C方式拼写。这个规则有两个例外QObject 和LocalObject 也是关键字,必须按照所C方式让首字母大写?

标识W以一个字母v_(d)后面可以跟Q意数目的字母或数字。Slice 标识W被限制在ASCII 字符范围内,不能包含非英语字母,与C++ 标识W不同, Slice 标识W不能有下划Uѝ这U限制初看上L得很苛刻Q但却是必要的:(x)保留下划U,各种语言映射p得了(jin)一个名字空_(d)不会(x)与合法的Slice 标识W发生冲H。于是,q个名字I间可用于存放从Slice 标识W派生的原生语言标识W,而不用担?j)其他合法的Slice 标识W会(x)y与之相同Q从而发生冲H??

标识W(变量名等{)(j)是大写不敏感的Q但大小写的拼写方式必须保持一_(d)看了(jin)后面的话Q再理解一下)(j)。例如,在一个作用域内, TimeOfDay 和TIMEOFDAY 被认为是同一个标识符。但是,Slice 要求你保持大写的一致性。在你引入了(jin)一个标识符之后Q你必须始终一致地拼写它的大写和小写字母;否则Q编译器׃(x)其视ؓ(f)非法而加以拒l。这条规则之所以存在,是要让Slice 既能映射到忽略标识符大小写的语言Q又能映到把大写不同的标识符当作不同标识W的语言。(可以q样理解Q变量名区分大小写,q且不可以是相同的单词)(j)

是关键字的标识符:你可以定义在一U或多种实现语言中是关键字的Slice 标识W。例如,switch是完全合法的Slice标识W,但也是C++和Java的关键字。语a映射定义?jin)一些规则来处理q样的标识符。要解决q个问题Q通常要用一个前~来映射后的标识W不再是关键字。例如, Slice 标识Wswitch 被映到C++ 的_cpp_switch Q以?qing)Java 的_switch。对关键字进行处理的规则可能?x)生难以阅ȝ源码。像native、throwQ或export q样的标识符?x)与C++ 或JavaQ或两者)(j)的关键字发生冲突。ؓ(f)?jin)让你和别h生活得更L一点,你应该避免用是实现语言的关键字的Slice 标识W。要CQ以后Ice 可能?x)增加除C++ 和Java 以外的语a映射。尽期望你ȝ出所有流行的~程语言的所有关键字q不合理Q你臛_应该量避免使用常用的关键字。用像self、importQ以?qing)while q样的标识符肯定不是好主意?

转义的标识符:在关键字的前面加上一个反斜线Q你可以把Slice 关键字用作标识符Q例?

struct dictionary { // 错误!
// ...
};
struct \dictionary { // OK
// ...
};

反斜U会(x)改变关键字通常的含义;在前面的例子中, \dictionary 被当作标识符dictionary。{义机制之所以存在,是要让我们在以后能够在Slice 中增加关键字Q同时尽量减对已有规范的媄(jing)响:(x)如果某个已经存在的规范碰巧用了(jin)新引入的关键字,你只需在新关键字前加上反斜U,p够修正该规范。注意,从风g_(d)你应该避免用Slice 关键字做标识W(即反斜U{义允怽q么做)(j)?

保留的标识符:Slice 为Ice 实现保留?jin)标识符Ice ?qing)以Ice QQ何大写方式Qv头的所有标识符。例如,如果你试囑֮义一个名为Icecream 的类型, Slice ~译器会(x)发出错误警告3。以下面M一U后~l尾的Slice 标识W也是保留的QHelper、Holder、PrxQ以?qing)Ptr。Java 和C++ 语言映射使用?jin)这些后~Q保留它们是Z(jin)防止在生成的代码中发生冲H?

Q注QICE 1.3的中文手册上没有“模块”这一部分Q模块来l织一l相关的语句是ؓ(f)?jin)解军_字冲H。模块可以包含所有合法的Slice语句和子模块。你可以用一些不常用的词来给最外层的模块命名,比如公司名、品名{等?

module ZeroC {

	module Client {
	// Definitions here...
	};

	module Server {
	// Definitions here...
	};
};

Slice要求所有的定义都是模块的一部分Q比如,下面的语句就是非法的?

interface I { // 错误:全局I间中只可以有模?
// ...
};

多个文g可以׃n同一个模块,比如Q?

module ZeroC {
// Definitions here...
};

//另一个文件中 :
module ZeroC { // OK, reopened module
// More definitions here...
};

把一个大的模块放到几个文件中d以方便编译(你只需重新~译被修改的文gQ而没有必要编译整个模块)(j)?

模块映的语言中的相应l构Q比?C++, C#, ?Visual Basic, Slice的modules被映ؓ(f)namespacesQjava中被映射为package.

除了(jin)数与特定的E序语言相关的调用之外,ice的绝大部分APIQ应用程序接口)(j)都是用Slice来定义的 。这样做的好处是可以用一个ICE API定义文g来支持所有的E序语言?

[注意] 注意
Z(jin)保证代码的简z,以后文章中提?qing)的Slice定义没有写出包含的模块,你要假定该语句是在一个模块中?

?nbsp;2.1. Slice的数据类?/B>

cd 取D?/TH> 大小Q单位:(x)bitQ?/TH>
bool false or true ?1
byte -128-127?-255 ?8
short 2Q?5?15Q? ?16
int 2Q?1?31Q? ?32
long 2Q?3?63Q? ?64
float IEEE的单_ֺ ?32 bits
double IEEE的双_ֺ ?64 bits
string 所有Unicode 字符Q除?jin)所有位为零的字W?/TD> 变长

用户定义的类?/H3>

  • 枚D:enum Fruit { Apple, Pear, Orange };

    q个定义引入?jin)一U名为Fruit 的类型,q是一U拥有自己权利的新类型。关于怎样把顺序|ordinal valuesQ赋l枚丄的问题, Slice 没有作出定义。例如,你不能假定,在各U实现语a中,枚DWOrange 的值都?。Slice 保证枚DW的序g(x)从左臛_递增Q所以在所有实现语a中,Apple 都比Pear 要小。与C++ 不同Q?Slice 不允怽控制枚DW的序|因ؓ(f)许多实现语言不支持这U特性)(j)Q?

    enum Fruit { Apple = 0, Pear = 7, Orange = 2 }; // 出错
    

    在实践中Q只要你不在地址I间之间传送枚丄的顺序|你就不用枚丄使用的值是多少。例如,发送? l服务器来表CApple 可能?x)造成问题Q因为服务器可能没有? 表示Apple。相反,你应该就发送值Apple 本n。如果在接收方的地址I间中, Apple 是用另外的顺序DC的Q?Ice run time ?x)适当地翻译这个倹{?

    与在C++ 里一P Slice 枚DW也?x)进入围l它的名字空_(d)所以下面的定义是非法的Q?

    enum Fruit { Apple, Pear, Orange };
    enum ComputerBrands { Apple, IBM, Sun, HP }; // Apple已经被定?
    

    Slice 不允许定义空的枚举?

  • l构

    Slice 支持含有一个或多个有名U的成员的结构,q些成员可以hLcdQ包括用户定义的复杂cd。例如:(x)
    struct TimeOfDay {
    short hour; // 0 - 23
    short minute; // 0 - 59
    short second; // 0 - 59
    };
    
    与在 C++ 里一Pq个定义引入?jin)一U叫作TimeOfDay 的新cd。结构定义会(x)形成名字I间Q所以结构成员的名字只需在围l它们的l构里是唯一的。在l构内部Q只能出现数据成员定义,q些定义必须使用有名字的cd。例如,你不可能在结构内定义l构Q?
    struct TwoPoints {
    struct Point { //错误!
    short x;
    short y;
    };
    Point coord1;
    Point coord2;
    };
    
    q个规则大体上适用于SliceQ类型定义不能嵌套(除了(jin)模块支持嵌套Q。其原因是,对于某些目标语言而言Q嵌套的cd定义可能?x)难以实玎ͼ而且Q即使能够实玎ͼ也会(x)极大C作用域解析规则复杂化。对于像S(chng)lice q样的规范语a而言Q嵌套的cd定义q无必要——你总能以下面的方式~写上面的定义(q种方式在风g也更加整z)(j)Q?
    struct Point {
    short x;
    short y;
    };
    struct TwoPoints { // Legal (and cleaner!)
    Point coord1;
    Point coord2;
    }
    
  • 序列

    序列是变长的元素向量Q?

    sequence<Fruit> FruitPlatter;
    

    序列可以是空的——也是_(d)它可以不包含元素Q它也可以持有Q意数量的元素Q直到达C的^台的内存限制?

    序列包含的元素自w也可以是序列。这U设计得你能够创徏列表的列表:(x)

    sequence<FruitPlatter> FruitBanquet;
    

    序列可用于构多种collectionQ比如向量、列表、队列、集合、包QbagQ,或是?wi)(ơ序是否重要要由应用军_Q如果无视次序,序列充当的就是集合和包)(j)?

    序列的一U特别的用法已经成了(jin)惯用手法Q即用序列来表示可选的倹{例如,我们可能拥有一个Part l构Q用于记录小汽R的零件的详细资料。这个结构可以记录这L(fng)资料Q零件名U、描q、重量、h(hun)|以及(qing)其他详细资料?备g通常都有序列P我们用一个long DC。但有些零gQ比如常用的Z钉,常常没有序列P那么我们在螺丝钉的序列号字段里要放进什么内容?要处理这U情况,有这样一些选择Q?

    • 用一个标记|比如Ӟ来指C“没有序列号”的情况?

      q种Ҏ(gu)是可行的Q只要确实有标记值可用。尽看h不大可能有h把零用作零g的序列号Q这q是不可能的。而且Q对于其他的|比如温度|在其cd的范围中的所有值都可能是合法的Q因而没有标记值可用?

    • 把序列号的类型从long 变成string?

      串自己有内徏的标记|也就是空Ԍ所以我们可以用IZ来指C?“没有序列号”的情况。这也是可行的,但却?x)让大多Ch感到不快Q我们不应该Z(jin)得到一个标记|而把某种事物自然的数据类型变成string

    • 增加一个指C符来指C序列号的内Ҏ(gu)否有?

      struct Part {
      string name;
      string description;
      // ...
      bool serialIsValid; // true if part has serial number
      long serialNumber;
      };
      

      对于大多Ch而言Q这也让厌,而且最l肯定会(x)让你遇到ȝ(ch)Q迟早会(x)有程序员忘记在用序列号之前(g)查它是否有效Q从而带来灾难性的后果?

    • 用序列来建立可选字D?

      q种技术用了(jin)下面的惯用手法:(x)

      sequence<long> SerialOpt;
      struct Part {
      string name;
      string description;
      // ...
      SerialOpt serialNumber; // optional: zero or one element
      };
      

      按照惯例Q?Opt 后缀表示q个序列是用来徏立可选值的。如果序列是I的Q值显然就不在那里Q如果它含有一个元素,q个元素是那个倹{这U方案明昄~点是,有h可能?x)把不止一个元素放入序列。ؓ(f)可选值增加一个专用的Slice 成分可以U正q个问题。但可选值ƈ非那么常用,不值得为它增加一U专门的语言Ҏ(gu)(我们看刎ͼ你还可以用类层次来徏立可选字D)(j)?

  • 词典

    词典是从键类型到值类型的映射。例如:(x)

    struct Employee {
    long number;
    string firstName;
    string lastName;
    };
    dictionary<long, Employee> EmployeeMap;
    

    q个定义创徏一U叫作EmployeeMap 的词典,把雇员号映射到含有雇员详l资料的l构。你可以自行军_键类型(在这个例子中是long cd的雇员号Q是否是值类型(在这个例子中是Employee l构Q的一部分——就Slice 而言Q你无需让键成ؓ(f)值的一部分?

    词典可用于实现稀疏数l,或是h非整数键cd的Q何用于查扄数据l构。尽含有键Q值对的结构的序列可用于创建同L(fng)事物Q词典要更ؓ(f)适宜Q?

    • 词典明确地表达了(jin)设计者的意图Q也是Q提供从值的域(domainQ到值的范围QrangeQ的映射Q含有键Q值对的结构的序列没有如此明确地表辑֐L(fng)意图Q?

    • 在编E语a一U,序列被实现成向量Q也可能是列表)(j)Q也是_(d)序列不大适用于内容稀疏的域,而且要定位具有特定值的元素Q需要进行线性查找。而词典被实现成支持高效查扄数据l构Q通常是哈希表或红黑树(wi)Q,其^均查找时间是O(log n)Q或者更好。词典的键类型无需为整型。例如,我们可以用下面的定义来翻译一周每一天的名称Q?

      dictionary<string, string> WeekdaysEnglishToGerman;
      

      服务器实现可以用键-值对Monday–Montag、Tuesday–DienstagQ等{,对这个映表q行初始化?

    • 词典的值类型可以是用户定义的Q何类型。但词典的键cd只能是以下类型之一Q?

      • 整型Qbyte、short、int、long、boolQ以?qing)枚丄型?j)

      • string

      • 元素cd为整型或string 的序?

      • 数据成员的类型只有整型或string 的结?

      复杂的嵌套类型,比如嵌套的结构或词典Q以?qing)Q点类型(float和doubleQ,不能用作键类型。之所以不允许使用复杂的嵌套类型,是因?x)词典的语a映射复杂化;不允怋用Q点类型,是因为Q点值在跨越机器界线Ӟ其表CZ(x)发生变化Q有可能D成问题的相等语义?

  • 帔R定义与直接量

    Slice 允许你定义常量。常量定义的cd必须是以下类型中的一U:(x)

    • 整型Qbool、byte、short、int、longQ或枚DcdQ?

    • float 或double

    • string

    下面有一些例子:(x)

    const bool AppendByDefault = true;
    const byte LowerNibble = 0x0f;
    const string Advice = "Don't Panic!";
    const short TheAnswer = 42;
    const double PI = 3.1416;
    enum Fruit { Apple, Pear, Orange };
    const Fruit FavoriteFruit = Pear;
    

    直接量(literalsQ的语法与C++ 和Java 的一P有一些小的例外)(j)Q?

    • 布尔帔R只能用关键字false和true初始化(你不能用0?来表Cfalse和trueQ?

    • 和C++ 一P你可以用十进制、八q制Q或十六q制方式来指定整数直接量。例如:(x)

      const byte TheAnswer = 42;
      const byte TheAnswerInOctal = 052;
      const byte TheAnswerInHex = 0x2A; // or 0x2a
      

      [注意] 注意
      如果你把byte 解释成数字、而不是位模式Q你在不同的语言里可能会(x)得到不同的结果。例如,在C++ 里, byte 映射到charQ取决于目标q_Q?char 可能是有W号的,也可能是无符L(fng)?/TD>
      [注意] 注意
      用于指示长常量和无符号常量的后缀QC++ 使用的l、L、u、UQ是非法的:(x)
      const long Wrong = 0u; // Syntax error
      const long WrongToo = 1000000L; // Syntax error
      
      • 整数直接量的值必落在其帔Rcd的范围内Q否则编译器׃(x)发出诊断消息?

      • 点直接量用的是C++语法Q除?jin)你不能用l或L后缀来表C扩展的点帔RQ但是, f 和F 是合法的Q但?x)被忽略Q。下面是一些例子:(x)

        const float P1 = -3.14f; // Integer & fraction, with suffix
        const float P2 = +3.1e-3; // Integer, fraction, and exponent
        const float P3 = .1; // Fraction part only
        const float P4 = 1.; // Integer part only
        const float P5 = .9E5; // Fraction part and exponent
        const float P6 = 5e2; // Integer part and exponent
        

      • 点直接量必落在其帔RcdQfloat 或doubleQ的范围内;否则~译器会(x)发出诊断警告?

      • 串直接量支持与C++ 相同的{义序列。下面是一些例子:(x)

        const string AnOrdinaryString = "Hello World!";
        const string DoubleQuote = "\"";
        const string TwoSingleQuotes = "'\'"; // ' and \' are OK
        const string Newline = "\n";
        const string CarriageReturn = "\r";
        const string HorizontalTab = "\t";
        const string VerticalTab = "\v";
        const string FormFeed = "\f";
        const string Alert = "\a";
        const string Backspace = "\b";
        const string QuestionMark = "\?";
        const string Backslash = "\\";
        70 Slice 语言
        const string OctalEscape = "\007"; // Same as \a
        const string HexEscape = "\x07"; // Ditto
        const string UniversalCharName = "\u03A9"; // Greek Omega
        和在 C++ 里一P盔R的串直接量会(x)q接hQ?
        const string MSG1 = "Hello World!";
        const string MSG2 = "Hello" " " "World!"; // Same message
        /*
        * Escape sequences are processed before concatenation,
        * so the string below contains two characters,
        * '\xa' and 'c'.
        */
        const string S = "\xa" "c";
        

        [注意] 注意
        Slice 没有null 串的概念
        const string nullString = 0; // Illegal!
        
        null 串在Slice 里根本不存在Q因此,在Ice q_的Q何地方它都不能用作合法的串倹{这一军_的原因是Q?null 串在许多~程语言里不存在

接口、操作,以及(qing)异常

见手?.......抄书好篏.........



늉散步 2005-12-13 12:00 发表评论
]]>
转蝲:学习(fn)ICE 3.0--初读代码http://www.shnenglu.com/klsmlzm/archive/2005/12/13/1711.html늉散步늉散步Tue, 13 Dec 2005 03:58:00 GMThttp://www.shnenglu.com/klsmlzm/archive/2005/12/13/1711.htmlhttp://www.shnenglu.com/klsmlzm/comments/1711.htmlhttp://www.shnenglu.com/klsmlzm/archive/2005/12/13/1711.html#Feedback0http://www.shnenglu.com/klsmlzm/comments/commentRss/1711.htmlhttp://www.shnenglu.com/klsmlzm/services/trackbacks/1711.html

初读代码

q一节大部分内容整理自ICE中文手册Q在q里我特别感谢马l达同志的翻译给我们的学?fn)带来?jin)方便?

L务端代码

文gserver.cpp. 

#include <Ice/Ice.h> 		
#include "../print.h"
using namespace std;
using namespace Demo;

//惯例Q用后缀I 表示q个cdC个接?
class PrinterI : public Printer {
public:
	virtual void printString(const string& s, const Ice::Current&);
};	 
/*
打开print.hQ看看PrinterI父类的定?

namespace Demo {
class Printer : virtual public Ice::Object {
public:

//U虚函数Q不能实例化
virtual void printString(const std::string&,
//W二个参数有~省|实现中可以不使用
const Ice::Current&= Ice::Current()) = 0;
};
};
*/

void PrinterI::printString(const string& s, const Ice::Current&)
{
	cout << s << endl;
}

int  main(int argc, char* argv[])
{	
	//E序的退出时的状态,是否成功执?
	int status = 0; 

	 //来包含I(xin)ce run time 的主句柄	(main handle)
	Ice::CommunicatorPtr ic;

	try {
	//初始化Ice run time Qargc和argv是run time命o(h)参数Q?
	//p个例子而言Q服务器不需要Q何命令行参数Q?
    //initialize q回一个指向Ice::Communicator对象的智能指针,
	//q个指针是Ice run time 的主句柄?
		ic = Ice::initialize(argc, argv);
	 
	 //调用Communicator 实例上的createObjectAdapterWithEndpointsQ?
	 //创徏一个对象适配?比如Q网卡就是一U适配??
	 //参数?SimplePrinterAdapter" Q适配器的名字Q?
	 //?default -p 10000"(用缺省协议(TCP/IPQ?侦听端口10000 的请求?
	 //昄Q在应用中硬~码对象标识和端口号Q是一U糟p的做法Q?
	 //但它目前很有效;我们在以后看到在架构上更加合理的做法?
		Ice::ObjectAdapterPtr adapter
			= ic->createObjectAdapterWithEndpoints(
			"SimplePrinterAdapter", "default -p 10000");

	  //服务器端run time 已经初始?实例化一个PrinterI 对象Q?
	  //为我们的Printer 接口创徏一个servantQserv 服务Q?ant?背一下单词)(j)?
		Ice::ObjectPtr object = new PrinterI;

	  //我们调用适配器的addQ告诉它有了(jin)一个新的servant Q?
	  //传给add 的参数是刚才实例化的servantQ再加上一个标识符?
	  //在这里,"SimplePrinter" 串是servant 的名?
	  //Q如果我们有多个打印机,每个打印机都可以有不同的名字Q?
	  //更正的说法是,都有不同的对象标识)(j)?
		adapter->add(object,
			Ice::stringToIdentity("SimplePrinter"));

		//调用适配器的activate Ҏ(gu)Ȁz适配?
		//Q适配器一开始是在暂停(holdingQ状态创建的Q?
		//q种做法在下面这L(fng)情况下很有用Q?
		//我们有多个servantQ它们共享同一个适配器,
		//而在所有servant实例化之前我们不惛_理请求)(j)?
		//一旦适配器被Ȁz,服务器就?x)开始处理来自客L(fng)h?
		adapter->activate();

		//最后,我们调用waitForShutdown?
		//q个Ҏ(gu)挂v发出调用的线E直到服务器实现l止
		//——或者是通过发出一个调用关闭run timeQ?
		ic->waitForShutdown();
	} 
	catch (const Ice::Exception& e) {
			cerr << e << endl;
		status = 1;
	} catch (const char* msg) {
		cerr << msg << endl;
		status = 1;
	}
	if (ic) {
		try {

		//必须调用Communicator::destroyl束Ice run time?
		//destroy ?x)等待Q何还在运行的操作调用完成?
		//此外Q?destroy q(sh)(x)保Mq未完成的线E都得以汇合QjoinedQ,
		//q收回一些操作系l资源,比如文g描述W和内存?
		//决不要让你的main 函数不调用destroy q?
		//否则Q后果无法想象?
			ic->destroy();

		} catch (const Ice::Exception& e) {
			cerr << e << endl;
			status = 1;
		}
	}
	return status;
}

注意Q尽以上的代码不算,但它们对所有的服务器都是一L(fng)。你可以把这些代码放在一个辅助类里,然后无需再ؓ(f)它费?j)?jin)QIce 提供?jin)这L(fng)辅助c,叫作Ice::ApplicationQ参?10.3.1 节)(j) 。就实际的应用代码而言Q服务器只有几行代码Q六行代码定义PrinterI c,再加上三2 行代码实例化一个PrinterI 对象Qƈ向对象适配器注册它?

dL(fng)代码

文gclient.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);

		//stringToProxy q回的代理(ProxyQ类型是Ice::ObjectPrxQ?
		//q种cd位于接口和类的(h)承树(wi)的根部(接口的基c)(j)?
		 Ice::ObjectPrx base 
		=ic->stringToProxy(	"SimplePrinter:default -p 10000");

		//但要实际要与我们的打印机交谈Q?
		//我们需要的是Printer 接口、不是Object 接口的代理?
		//为此Q需要调用PrinterPrx::checkedCast q行向下转换Q向下{型)(j)?
		//q个Ҏ(gu)?x)发送一条消息给服务器,
		//询问“这是Printer 接口的代理吗Q?
		//如果回答“是”,׃(x)q回Printer 的一个代理;
		//如果代理代表的是其他cd的接口,q回一个空代理
		PrinterPrx printer = PrinterPrx::checkedCast(base);
		
		//试向下转型是否成功Q若不成功,抛出出错消息ƈl止客户?
		if (!printer) 	throw "Invalid proxy";

		//现在Q我们在我们的地址I间里有?jin)一个激zȝ代理Q?
		//可以调用printString Ҏ(gu)Q?
		//把n誉已久的 "Hello World!" 串传l它?
		//服务器会(x)在它的终端上打印q个丌Ӏ?
		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;
}

如果出现M错误Q客户会(x)打印一条出错消息。例如,如果我们没有先启动服务器p行客P我们?x)得刎ͼ?x)

Network.cpp:471: Ice::ConnectFailedException:
connect failed: Connection refused

(׃windows下的命o(h)行窗口在出错后会(x)一闪就消失Q不q我们可以在client.cpp的main函数的return status;之前加上system("PAUSE");然后再在VS2003.net中把client讄为启动项目,重新~译Q运行。OKQ可以看到结果了(jin)?



늉散步 2005-12-13 11:58 发表评论
]]>
转蝲:学习(fn)ICE 3.0--准备工作http://www.shnenglu.com/klsmlzm/archive/2005/12/13/1710.html늉散步늉散步Tue, 13 Dec 2005 03:56:00 GMThttp://www.shnenglu.com/klsmlzm/archive/2005/12/13/1710.htmlhttp://www.shnenglu.com/klsmlzm/comments/1710.htmlhttp://www.shnenglu.com/klsmlzm/archive/2005/12/13/1710.html#Feedback5http://www.shnenglu.com/klsmlzm/comments/commentRss/1710.htmlhttp://www.shnenglu.com/klsmlzm/services/trackbacks/1710.html

准备工作

按照某h的说法:(x)跨^台的CQ+|络~程ICE才是王道。于是,我学?fn)ICE?

ICE才出来两q_(d)是“一U现代的面向对象中间Ӟ可用于替代像CORBA或COM/DCOM/COM+q样的中间g。在易于学习(fn)的同Ӟ它ؓ(f)各种有着苛刻的技术要求的应用提供?jin)强大的|络基础设施。”Ice 3.0 已实现对C++, Java, Python, PHP, C# ?Visual Basic 的支持?

q里我就不多说了(jin),大家可以参考这文章:(x)《反叛之冎ͼ(x)Internet Communications Engine 》。大家可以下载的ICE的官方参考手册,有中文版Q不q是1.3.0? 英文的是3.0版?

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

ICE自定义了(jin)一USLICE语言Q目的是定义接口Q作用主要应该是保持对象调用或者数据传输时的语a无关性?

开发一个ICE应用E序可以分ؓ(f)三步:

  1. 写一个Slice定义, q且~译?/P>

  2. 写服务端, q编译它

  3. 写客L(fng), q编译它

OKQ写一个小E序Q实现客户发送要打印的文本给服务器,再由服务器把文本发给打印机(q里我们用屏q显C替代)(j),q里对代码解读请见下一章,q里不多说?

  1. 写一个Slice定义, q且~译它:(x)

    文gPrinter.ice. 

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

    q个文g很简? 但需要注? 在区分大写的系l上, 扩展名一定是写.

    ~译也很?首先认你已你的bin目录加到pȝ的环境变量Path?然后把上面这个片断保存成Printer.ice, 最后执行slice2cpp Printer.ice, 执行后的l果应该是自动生成了(jin)printer.h和printer.cpp.

  2. 写服务端, q编译它

    文gserver.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的配|ؓ(f)?

    1. 把ice的include加入VC7.1的引用文件目?把ice的lib目录加入VC7.1的库文g目录。然后再把安装目录下的bin文gҎ(gu)加到pȝ的环境变量Path中,最后,把bin文g夹下的所有DLL文g都Copy到Windows安装目录下的System32文g夹下Qwin98下是System文g夹?Q(当然QDLL文g的问题(sh)可以通过修改环境变量来解冻I不过是那个变量呢QWho can tell me?Q?

    2. 新徏一个CQ+的Win32的命令台控制E序Qƈ且设|ؓ(f)I项目, 把server.cpp, printer.cpp和printer.h加入q个目Qprinter.cpp和printer.h攑֜目的目录的外一层目录)(j)

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

      目Q》配|属?》C/C++-》语a-》启用运行时cd信息/GR 开?

      讄Q项目-》属性-》链接器Q》输入-》加入iced.lib iceutild.libQ此处一定要把realse库和debug库分? debug库后有个d

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

    5. OK,~译

  3. 写客L(fng)Qƈ~译?/P>

    文gclient.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;
    }
    

    d一个新目到当前解x(chng)案,按照上面的方法,对client再一ơ进行设|?/P>

    在解x(chng)案管理器的解x(chng)案上点击右键Q选择批生成Debug版本Q然到用资源理器到两个解决Ҏ(gu)的目录下的Debug文g夹中执行生的可执行文g。先q行server.exe, 然后q行client.exe, 哈哈, 是不是在server.exe的窗口里出现?jin)Hello World!Q运行一ơclient.exeQ出C条)(j)

 

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



늉散步 2005-12-13 11:56 发表评论
]]>
97Ʒ˾þþô߽97| þùŷպƷ| þݹֻƬ| ƷþþþþĻһ| Ůͬþ| þþþþþƷþþþ| þav뾫Ʒ˳| Ůͬþ| ƷŮٸAVѾþ| ҹþþƷ | þþƷרѶ| þþƷAVþþ| պŷۺϾþ | þþŷղ | Ʒһþ㽶߿ | ˳þõӰվ| ۺϾþһ | Ʒ99þþþþwww| ھƷþþþþþ| ˺ݺۺϾþ޸| ɫۺϺϾþۿ| ľþþƷ| Ʒþù鶹99վ| 99þ99þþƷƬ| ƬҹƬþ | ղþǿѵĿ| 2021ƷþþƷ| Ʒ԰״̼þþ| Ʒ99þþþþwww| ۺϾþþþþĻ޹ۺһ| ģ˽ĹƷþ| ޹Ʒþþѿ| ۲ӰԺþùƷ| þþþþþþþþ| 91þø˾Ʒ| þþþþþþòҰ߳| 99þۺϺݺۺϾþ| ޹ŷۺϾþ| þþƷѹۿ97| þԭƷ| ˾þô߽ۺվ|