??xml version="1.0" encoding="utf-8" standalone="yes"?>欧美亚洲国产精品久久久久,99久久国产精品免费一区二区,91久久婷婷国产综合精品青草http://www.shnenglu.com/klsmlzm/仗剑走天?/description>zh-cnWed, 07 May 2025 15:01:59 GMTWed, 07 May 2025 15:01:59 GMT60CVS服务器的相关配置及用[ Server of CVS Configure and Usage for linux]---?此教E是"火山?提供?-)http://www.shnenglu.com/klsmlzm/archive/2006/11/28/15737.html늉散步늉散步Tue, 28 Nov 2006 08:18:00 GMThttp://www.shnenglu.com/klsmlzm/archive/2006/11/28/15737.htmlhttp://www.shnenglu.com/klsmlzm/comments/15737.htmlhttp://www.shnenglu.com/klsmlzm/archive/2006/11/28/15737.html#Feedback3http://www.shnenglu.com/klsmlzm/comments/commentRss/15737.htmlhttp://www.shnenglu.com/klsmlzm/services/trackbacks/15737.html 一、安?/span>

1 ?/span> linux 安装好后已经装好?/span> cvs Q可?/span> rpm -qa|grep cvs 查看?/span>

如果没有安装你可以在 Redhat W?/span> 2 张光盘上扑ֈQ另外你也可以在|上下蝲到最新的 rpm 包。很Ҏ找,其实不存在什?/span> linux 版本?/span>

 

2 、创?/span> cvs 使用的目录: mkdir /home/mycvstest

 

3 、创?/span> cvs 使用的用户和l?/span>

groupadd cvs

useradd -g cvs -G cvs –d /home/mycvstest cvs

passwd cvs

 

4 、修?/span> mycvstest 的用P chown -R cvs:cvs /home/mycvstest

                        chmod 755 /home/mycvstest

 

5 、切换用P su cvs

 

6 、创建源码仓库: mkdir /home/mycvstest/drcls drclgw

 

7 、初始化源码仓库Q?/span> cvs -d /home/mycvstest/drcls init

                   cvs -d /home/mycvstest/drclgw init

                   chmod 755 /home/mycvstest/drcls drclgw

初始化后可以在目录下见到新增加的 CVSROOT 目录Q?/span> cvs 所有的控制信息都在q个目录里?/span>

 

8 、退回到 root 用户Q徏?/span> CVS 服务启动文gQ?/span> CVS 使用 xinetd 方式启动?/span>  

 

vi /etc/xinetd.d/cvspserver

 

service cvspserver

{

disable = no

flags = REUSE

socket_type = stream

wait = no

user = root

server= /usr/bin/cvs

server_args= -f --allow-root=/home/mycvstest/drcls

--allow-root=/home/mycvstest/drclgw pserver

log_on_failure += USERID

}

 

注:U色的参数很重要Q由?/span> xinetd ?/span> server_args 长度限制 , 当你惌行很多的单个仓库的时?/span> ( 是有很多个模块Ӟ比如 drcrgw), 但在 server_args 中无法输入这么多单个的仓库, 可以采取以下方式解决Q现在实验室 90 上就用的q种方式Q:

 

#> vi cvspserver

 

service cvspserver

{

        disable = no

        socket_type = stream

        wait = no

        user = root

        server = /usr/bin/cvs.run

        server_args =""

}

~写 cvs.run 脚本

vi /cvsroot/cvs.run

#!/bin/bash

/usr/bin/cvs -f

--allow-root=/home/mycvstest/drcls

--allow-root= /home/mycvstest/drclgw

pserver

 

chmod a+x cvs.run

 

9 、加?/span> cvs 服务Q?/span>

 

#>vi /etc/services

 

cvspserver 2401/tcp #pserver cvs service

cvspserver 2401/udp #pserver cvs service

 

10 、启?/span> cvs 服务Q?/span>

 

#> service xinetd restart

 

11 、检?/span> cvspserver 服务是否已经启动Q?/span>

 

#> netstat -l |grep cvspserver

应该有如下结果:

tcp 0 0 *:cvspserver *:* LISTEN

 

 

二、用和理

1 、创?/span> cvs 用户Q?/span>

cd /home/mycvstest/drcls/CVSROOT

htpasswd –c passwd zhangcan (htpasswd 命o要安?/span> apache 后才有,此命令创Z?/span> passwd 文gQ里面内容ؓ新徏 cvs 用户的用户名和密?/span> )

vi passwd ( 在新建的用户后手工加入用户属于的l?/span> cvs)

例如Q?/span> zhangcan:dgeagasdgasdr:cvs  蓝色字符串表C加密后的密码?/span>

 

2 、赋予用戯写权?/span>

手工?/span> CVSROOT 目录中徏?/span> readers ?/span> writers 文g?/span> Readers 文g中的用户只有L限, writers 中的用户hd权限Q一行只写一个用户名?/span>

 

3 、登?/span> cvs

在客h Linux 下面用命令:

export CVSROOT=:pserver:zhangcan@192.168.100.197:/home/mycvstest/drcls

cvs login

 

4 、向源码仓库中导入源?/span>

首先q入你本Z安装源码的目录,然后使用以下命oQ?/span>

cvs import –m “this is my soure code?drcls NISEC test start

-m 表示?/span> cvs 历史文g昄的消息, drclst Z指定的源码目录名Q?/span> NISEC Z应商标签Q?/span> test 为发行标{(q两可以不要)Q?/span> start 必须要?/span>

 

5 ?/span> checkout 出需要修改的源代?/span>

cvs co drcls  在你的当前目录下会发现多了一?/span> drcls 目录Q要修改的源码都在里?/span>

co ?/span> checkout 的简?/span>

 

6 、提交修?/span>

假设刚才?/span> readme 文gq行了修改,现在提交

cvs commit –m “modify a few of wrong words?span style="mso-spacerun: yes">  readme

命o执行后会提示版本已经改ؓ 1.2 ?/span>

 

7 ?/span> checkout Z前的版本

如果xZ前的版本可以用以下命令:

cvs co –r 1.1 drcls/readme 或?/span> cvs –D yesterday drcls/readme

 

8 、删除文?/span>

若想从源码仓库中删除 readme 文gQ首先应把客h工作目录中的 readme 文g删除Q然后?/span> cvs 的删除命令,最后提交删除,程如下Q?/span>

rm readme

cvs rm readme

cvs commit –m ?/span> 现在不需要这?/span> readme 文g ?span style="mso-spacerun: yes">  readme

如果pȝcM错误Q?/span> cannot remove file `INSTALL' which has a numeric sticky tag of `1.1'

可以用命?/span> cvs update –A readme 后再删除文g?/span>


以上为火山哥提供?以下是我d的部?
1.在reader和writes文g中添加用用h要注?当在reader中添加了某一只读用户后就不要在writers中添加此用户,如果在两个文件中都添加同一用户的话,在用cvs?CVS服务器会把此用户当做只读用户看待,当用一些命令如import时会产生权限问题,以下是linux关于此问题的说明:
/* This command has the potential to modify the repository, so
   * we check if the user have permission to do that.
   *
   * (Only relevant for remote users -- local users can do
   * whatever normal Unix file permissions allow them to do.)
   *
   * The decision method:
   *
   *    If $CVSROOT/CVSADMROOT_READERS exists and user is listed
   *    in it, then read-only access for user.
   *
   *    Or if $CVSROOT/CVSADMROOT_WRITERS exists and user NOT
   *    listed in it, then also read-only access for user.
   *
   *    Else read-write access for user.
   */



늉散步 2006-11-28 16:18 发表评论
]]>
在VC++6.0 SP6 下配|ICE工程[DEBUG版本]--config ice project(debug) for vc++6.0 with sp6http://www.shnenglu.com/klsmlzm/archive/2006/09/18/12686.html늉散步늉散步Mon, 18 Sep 2006 09:58:00 GMThttp://www.shnenglu.com/klsmlzm/archive/2006/09/18/12686.htmlhttp://www.shnenglu.com/klsmlzm/comments/12686.htmlhttp://www.shnenglu.com/klsmlzm/archive/2006/09/18/12686.html#Feedback6http://www.shnenglu.com/klsmlzm/comments/commentRss/12686.htmlhttp://www.shnenglu.com/klsmlzm/services/trackbacks/12686.html刚学习ICE?在VC++6.0下配|ICE工程直是个恶?L配不来DEBUG版本?开发全在RELEASE版本?很痛?最q研I了?成功的配|成功了,Ҏ如下:

1.Project Settings >> C/C++(Tab) >> Category:Code Generation >> User run-time library:Debug Multithreaded DLL

2.Project Settings >> C/C++(Tab) >> Category:Preprocessor >> Additional include directories:(在此中填入一个点".",表示根目?

3.Project Settings >> C/C++(Tab) >> Category:C++ Language >> N?Enable Run-Time Type Information(RTTI)"?br />
4.Project Settings >> Link(Tab) >> Category:General>>?Object/library modules:"框中的未首加入两个包"iced.lib"?iceutild.lib"


q样,整个ICE工程的DEBUG版本徏立完成了.
以上Ҏ?VC++6.0 SP6 ?ICE3.0.0 下通过



늉散步 2006-09-18 17:58 发表评论
]]>
LINUX下简单的~译和用动态链接库[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,
然后供其它程序用时直接调用里面闭的函数即?实现的代码的重用,也节省了
盘I间(q点可能是次要的?.在WIDOWS下利用VC++可方便的生成DLL,在LINUX下则需要通过
各种~译命o来实?对于像我q种菜鸟U程序员来说是个不小的挑?
下面用个单的例子来说明生成一?SO文g和如何用它:
1.我这有几个文?
ConfigMap.cpp ConfigMap.h (读配|文件类)GetWinState.cpp GetWinState.h(ICE接口文g,由SLICE生成) GetWinSysState.cpp GetWinSysState.h (q程接口实现文g)
SocDbInfo.cpp(装的一个类,用于调用ICE接口实现相关操作)
说明:此程序是Z获得q程L(WINDOWS)上一些系l信?比如:CPU占用?盘使用情况,数据
库连接状?内存使用情况{?
我想利用q些文g生成动态链接库.SO,主要是调用SocDbInfo.cpp里的c?然后可以拿到L一个系l中(LINUX)ȝ.
2.开始编?$c++ -I. -I$ICE_HOME/include -c *.cpp
~译后生成连接文?我一直这样叫,可能不对?,即以.Ol尾?br />3.生成动态链接库:$c++ -shared -o libMyApp.so *.o -L$ICE_HOME/lib -lIce -lIceUtil
q样q成了libMyApp.so文g,x们所要的
4.使用动态链接库:
新徏两个文gDemo.cpp Demo.h(使用libMyApp.so提供的一些函?,
在Demo.h中声明了libMyApp.so中提供的函数和结构体,
Demo.h:代码如下:

struct MemoryInf
{
 int TotalMem;//×ÜÄÚ´æ´QС
 int ValidMem;//HÉʹÓÃÄÚ´æ´QС
 int VirtualMem;//ÐéÄâÄÚ´æ´QС
};
struct DiskInf
{
 int TotalSpace;//Ó̔ÅÌ´QС
 int FreeSpace;//ÊnÓàHÕä´QС
};
struct DbInf
{
 int DbStat;//Êý¾ÝHâ×´ÌR:"0"uTʾÊý¾ÝHâ´ÔÚ¹ØuÕ×´ÌR,"1"uTʾÊý¾ÝHâÕýn´òHª,"2"uTʾÊý¾ÝHâ´ÔÚ¹ÒÆð×´ÌR
 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[])
{

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


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



늉散步 2006-04-21 15:06 发表评论
]]>
C++~程中,利用WINDOWS API获得pȝ状态信息[CPU占用率,盘使用情况Q内存用情况]http://www.shnenglu.com/klsmlzm/archive/2006/04/14/5522.html늉散步늉散步Fri, 14 Apr 2006 03:35:00 GMThttp://www.shnenglu.com/klsmlzm/archive/2006/04/14/5522.htmlhttp://www.shnenglu.com/klsmlzm/comments/5522.htmlhttp://www.shnenglu.com/klsmlzm/archive/2006/04/14/5522.html#Feedback3http://www.shnenglu.com/klsmlzm/comments/commentRss/5522.htmlhttp://www.shnenglu.com/klsmlzm/services/trackbacks/5522.html#include <Ice/Ice.h>
#include <iostream>
#include <GetWinSysState.h>
#include <Winbase.h>
#include <conio.h>
#include <stdio.h>
#include <fstream>
#include <iostream>
#include <string>
#include <direct.h>

#define SystemBasicInformation       0
#define SystemPerformanceInformation 2
#define SystemTimeInformation        3

#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))
//ICE预编译语?/p>

#ifdef _DEBUG
#pragma comment(lib, "iced.lib")
#pragma comment(lib, "iceutild.lib")
#else
#pragma comment(lib, "ice.lib")
#pragma comment(lib, "iceutil.lib")
#endif

typedef struct
{
    DWORD   dwUnknown1;
    ULONG   uKeMaximumIncrement;
    ULONG   uPageSize;
    ULONG   uMmNumberOfPhysicalPages;
    ULONG   uMmLowestPhysicalPage;
    ULONG   uMmHighestPhysicalPage;
    ULONG   uAllocationGranularity;
    PVOID   pLowestUserAddress;
    PVOID   pMmHighestUserAddress;
    ULONG   uKeActiveProcessors;
    BYTE    bKeNumberProcessors;
    BYTE    bUnknown2;
    WORD    wUnknown3;
} SYSTEM_BASIC_INFORMATION;

typedef struct
{
    LARGE_INTEGER   liIdleTime;
    DWORD           dwSpare[76];
} SYSTEM_PERFORMANCE_INFORMATION;

typedef struct
{
    LARGE_INTEGER liKeBootTime;
    LARGE_INTEGER liKeSystemTime;
    LARGE_INTEGER liExpTimeZoneBias;
    ULONG         uCurrentTimeZoneId;
    DWORD         dwReserved;
} SYSTEM_TIME_INFORMATION;


// ntdll!NtQuerySystemInformation (NT specific!)
//
// The function copies the system information of the
// specified type into a buffer
//
// NTSYSAPI
// NTSTATUS
// NTAPI
// NtQuerySystemInformation(
//    IN UINT SystemInformationClass,    // information type
//    OUT PVOID SystemInformation,       // pointer to buffer
//    IN ULONG SystemInformationLength,  // buffer size in bytes
//    OUT PULONG ReturnLength OPTIONAL   // pointer to a 32-bit
//                                       // variable that receives
//                                       // the number of bytes
//                                       // written to the buffer
// );
typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);

PROCNTQSI NtQuerySystemInformation;

/*
  功能:得到CPU使用状?br />  参数:?br />  q回?内存占用?br />  作?늉散步
*/
int GetCpuStat()
{
 SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
    SYSTEM_TIME_INFORMATION        SysTimeInfo;
    SYSTEM_BASIC_INFORMATION       SysBaseInfo;
    double                         dbIdleTime;
    double                         dbSystemTime;
    LONG                           status;
    LARGE_INTEGER                  liOldIdleTime = {0,0};
    LARGE_INTEGER                  liOldSystemTime = {0,0};
 int UsageCpu = 0;
    NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
  GetModuleHandle("ntdll"),
  "NtQuerySystemInformation"
  );
 
    if (!NtQuerySystemInformation)
        return 0;
 
    status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
    if (status != NO_ERROR)
        return 0;
    
 for( int t = 0 ; t < 2 ; t++ )
    {
  status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0);
        if (status!=NO_ERROR)
            return 0;
  
        status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL);
        if (status != NO_ERROR)
            return 0;
  
  if (liOldIdleTime.QuadPart != 0)
  {
            dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
            dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
   
            dbIdleTime = dbIdleTime / dbSystemTime;
   

            dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5;
   UsageCpu = (int)dbIdleTime;

  }
  
        // store new CPU's idle and system time
        liOldIdleTime = SysPerfInfo.liIdleTime;
        liOldSystemTime = SysTimeInfo.liKeSystemTime;
  
        // wait one second
        Sleep(500);
    }
 return UsageCpu;
 
}


/*
  功能:得到内存使用状?br />  参数:?br />  q回?内存信息l构体[包括ȝ物理内存,q可使用内存,虚拟内存,单位为K]
  作?늉散步
*/
MemoryInf MemorySta()
{
 MemoryInf tmp;//在ICE SLICE里定义的信息l构?br /> MEMORYSTATUS memStatus;
 GlobalMemoryStatus(&memStatus);
 DWORD tom=memStatus.dwTotalPhys/1024;
 DWORD mem=memStatus.dwAvailPhys/1024;
 DWORD res=memStatus.dwAvailVirtual/1024;
 tmp.TotalMem = (int)tom;
 tmp.ValidMem = (int)mem;
 tmp.VirtualMem = (int)res;
 return tmp;
}


/*
 功能:得到盘使用情况
 参数:?br /> q回?盘信息l构?br /> 作?늉散步
*/
DiskInf GetDiskSta()
{
 ULARGE_INTEGER FreeAvailable,TotalNum,TotalFreeNum;

 char p[3];
 bool b_flag;
 DiskInf tmp;//ICE SLICE里定义的盘信息l构?br /> tmp.TotalSpace = 0;
 tmp.FreeSpace = 0;
 //得到有效的驱动器?即盘W?
 for( int drive = 1; drive <= 26; drive++ )
 {
  if( !_chdrive( drive ) )
  {
   memset( p , 0 , sizeof(p));
   p[0] = drive + 'A' - 1;
   p[1] = ':';
   p[2] = '\0';
   b_flag = GetDiskFreeSpaceEx( p ,&FreeAvailable,&TotalNum,&TotalFreeNum );
   if( b_flag )
   {
    tmp.TotalSpace += (int)(TotalNum.QuadPart/(1024*1024));
    tmp.FreeSpace += (int)(FreeAvailable.QuadPart/(1024*1024));
   }
  }
 }
 return tmp;
}

int main()
{
   return 1;
}



늉散步 2006-04-14 11:35 发表评论
]]>
C++风云20?C++图书介绍http://www.shnenglu.com/klsmlzm/archive/2006/02/28/3576.html늉散步늉散步Tue, 28 Feb 2006 09:07:00 GMThttp://www.shnenglu.com/klsmlzm/archive/2006/02/28/3576.htmlhttp://www.shnenglu.com/klsmlzm/comments/3576.htmlhttp://www.shnenglu.com/klsmlzm/archive/2006/02/28/3576.html#Feedback0http://www.shnenglu.com/klsmlzm/comments/commentRss/3576.htmlhttp://www.shnenglu.com/klsmlzm/services/trackbacks/3576.html?CSDN 孟岩  转蝲?005q第11期《程序员》杂?/FONT>

不知不觉Q?SPAN lang=EN>C++q来了自?SPAN lang=EN>20岁的生日?SPAN lang=EN>20q来Q?SPAN lang=EN>C++从一个实验室语言成长Y件业一主DaQ在实际应用中取得了巨大的成功,同时也催生了大量为技术h员耳熟能详的经典技术著作,比如Bjarne Stroustrup的?SPAN lang=EN>TC++PL》和?SPAN lang=EN>D&E》,Stan Lippman的?SPAN lang=EN>C++ Primer》,Scott Meyers的?SPAN lang=EN>Effective C++》,GoF的?SPAN lang=EN>Design Patterns》,Andy Koenig的?SPAN lang=EN>Ruminations on C++》,Herb Sutter的?SPAN lang=EN>Exceptional C++》,Andrei Alexandrescu的?SPAN lang=EN>Modern C++ Design》,Addison Wesley的?SPAN lang=EN>C++ in Depth”系列等?SPAN lang=EN>C++领域的一些经典图书不但对?SPAN lang=EN>C++语言的发展vC巨大的推动作用,而且对于其他相关技术领域也起到了指导和促进作用。例?SPAN lang=EN>Scott Meyers的?SPAN lang=EN>Effectivepd”,开辟了技术图书写作的新风|而?SPAN lang=EN>Design Patterns”的影响Q更是远q超?SPAN lang=EN>C++的范畴。这些经典的好书Q已l成?SPAN lang=EN>C++辉煌历史的一部分而被Z铭记?SPAN lang=EN> 

20q后的今天,软g产业的规模和环境已经发生了深ȝ变化。如今企业应用整合与开发的d主要?SPAN lang=EN>Java?SPAN lang=EN>C#?SPAN lang=EN>Visual Basic以及各种新型动态语a来承担,?SPAN lang=EN>C++的应用场合也有所收羃Q不再是?SPAN lang=EN>1990q代中期那样从上C包打天下Q而是呈现出鲜明的应用领域特色。相应的Q近期的C++技术图书也更加注重在特色领域的发挥。下面我们分别从几个角度来了解近?SPAN lang=EN>C++图书的热点,q且展望未来一q中C++技术图书中值得注意的选题?SPAN lang=EN> 

   

l典著作全面L 

q一两年Q一大批l典技术图书都l历了一ơ更新换代,C++l典图书自然也不例外。第一个要说的是Scott Meyers的?SPAN lang=EN>Effective C++》。这本书?SPAN lang=EN>1991q推出第一版,1998q推出第二版Q在C++技术的传播与教育方面居功至伟。包括我在内的很?SPAN lang=EN>C++开发者都是通过阅读q本书而寻得升堂入室的门径。今q_?SPAN lang=EN>Effective C++》推ZW三版。这一版决不是W二版的单修订,而是Ҏ八年?SPAN lang=EN>C++所发生的巨大变化而进行的一ơ全面改写,几乎是一本全新的书。其内容늛了旧版的_NQ也体现了诸?SPAN lang=EN>Boost库?SPAN lang=EN>TR1标准{?SPAN lang=EN>C++领域最新成果。如果说q本书的内容发生了重大的变化Q那么可以说不变的是q本书的C——它仍然是每个严肃的C++开发者都应当反复阅读领悟的重要作品?SPAN lang=EN> 

另一本翻新的著作?SPAN lang=EN>Stan Lippman的?SPAN lang=EN>C++ Primer》第四版。这本书的历史地位无需赘言Q迄今ؓ止仍然是?SPAN lang=EN>C++介绍最全面的一本著作。第四版q行了大q度的删修,幅减少q?SPAN lang=EN>300,而内容也大幅修改Q以反映C++q年来的变化。对于希望系l学?SPAN lang=EN>C++的新手,或者希望拥有一本手册以备查的老手来说Q这本书的地位是不可取代的?SPAN lang=EN> 

有传a?SPAN lang=EN>GoF打算L?SPAN lang=EN>Design Patterns”。该书第一版于1995q初版,此后十年Q设计模式领域的理论探讨和实践基本上仍然围绕q本书中的观点和内容q行Q少有突破。已l有不少开发者对于这U情况表CZ不满Q认为初版中的一些观点已l过Ӟ甚至对现在的一些技术应用构成思想上的绊。但是此书实在声名太盛,真正的突破恐怕只能由GoF自己完成Q因此本书新版如果推出,必将是技术界内的一桩大事。不q传a亦称Q?SPAN lang=EN>GoF对于新版?SPAN lang=EN>Design Patterns”是否l?SPAN lang=EN>C++作ؓC语言存在分歧。不怎样Q相信广大读者会对这本书抱有高度的关注?SPAN lang=EN> 

新锐佳作剑走偏锋 

q年来,一?SPAN lang=EN>C++技术新锐崛Pl我们带来了一批o目一新的C++好书。在技术上Q这批图书偏重于C++模板风格的y妙运用,富于而对实践的关注略显不뀂这cd书以2001q?SPAN lang=EN>Andrei Alexandrescu的?SPAN lang=EN>Modern C++ Design》ؓ开端,之后又有?SPAN lang=EN>Boost Graphic Library》,?SPAN lang=EN>C++ Template Metap- rogramming》等。这些书一度以其新颖的思想和奇妙的技巧吸引了大家的目光,但由于缺乏实늚支撑Q逐渐褪去光环。这两年Q这c题材逐渐~减。即使像Andrei Alexandrescu那样的模板技术奇才,最q与Herb Sutter合作的?SPAN lang=EN>C++ Coding Standard》也q没有过多地炫耀模板技巧,而是中规中矩地对C++~码的经验做了脓q实늚ȝ。这本书?SPAN lang=EN>Steve McConnell的经典著作?SPAN lang=EN>Code Complete II》相配合Q应成ؓ每一?SPAN lang=EN>C++开发者必ȝ基本著作Q将帮助读者奠定坚实的~码和微观设计技术基?SPAN lang=EN> 

Boost?SPAN lang=EN>C++Ch皆知的“准标准库”,其中大量的组件已l基本成熟ƈ可供应用。最q?SPAN lang=EN>Bjorn Karlsson撰写的?SPAN lang=EN>Beyond C++ Standard Library: An Introduction to Boost》是市面上第一本全面介l?SPAN lang=EN>Boost的著作。对于那些勇于吃螃蟹?SPAN lang=EN>C++先锋开发者来_q本书无疑是值得一ȝ。不q在C++CQ对Boost库还存在争议。大部分C++实践者比较保守,q本书对他们的吸引力恐怕将打折扣?SPAN lang=EN> 

Stephen Dewhurst是近q来比较z跃的新锐作Ӟ他的两本书?SPAN lang=EN>C++ Gotchas》和?SPAN lang=EN>C++ Common Knowledge》,单独来看都是值得一ȝ好书Q可惜现在不?SPAN lang=EN>1995q_而是2005q_Scott Meyers?SPAN lang=EN>Herb Sutter煌煌巨著已然危急九五,Dewhurst只好自叹施手略慢。不q我们希望他能够再接再厉Q找到创新点Q突破前人?SPAN lang=EN> 

相比之下Q中文版卛_问世的?SPAN lang=EN>Imperfect C++》就比较有新意,很值得一读,以至?SPAN lang=EN>Bjarne Stroustrup都相当赞赏。这?SPAN lang=EN>C++之父表示Q如果不是因书太厚,他一定会其U_著名的?SPAN lang=EN>C++ in Depth”系列。这在事实上肯定了本书的高质量。我个h认ؓQ这本书是一q来出版的最值得_读?SPAN lang=EN>C++著作Q其中对于不实践中l常遇到的难题进行了深入的分析,l出了实实在在的解决Ҏ。作?SPAN lang=EN>Matt Wilson凭借此书以及其pd模板E序库崛起ؓC++C中引人注目的新星Q实在可喜可贺?SPAN lang=EN> 

   

关键领域期待佳作 

未来C++主要在pȝU复杂应用程序、高性能、实时中间g及嵌入式领域施展Q同Ӟ随着多核CPU的的普及和网l安全重要性的I前提升Q在q发E序设计和安全程序设计方面,C++也将获得新的应用I间。因此,在这些具体领域的C++著作更值得x?SPAN lang=EN> 

1996q_John Lakos出版了?SPAN lang=EN>Large Scale C++》一书,该书??SPAN lang=EN>C++ In Depth”系列中的?SPAN lang=EN>Applied C++》一P?SPAN lang=EN>C++著作中极数实战z佳作,其中字字句句都来自于作者丰富的实际目l验Q对于一U的C++开发者来说是特别值得咀g味的好书。可惜这本书在国内一直没有得到应有的重视Q这可能跟本书中译本出版旉q晚Q且译质量不佳有关。好消息是,John Lakos卛_?SPAN lang=EN>2006q推出其C?SPAN lang=EN>Scalable C++》。我本h此书视为未来一q中C++领域最令h期待的作品。这一斚w是出于我对于作者的高度信QQ另一斚w是由于该书题材的极端重要性。该书副标题为“基于组件的软g开发”,而“组件化”这一主题Q是C++十几q来的一块心病。在未来Q无?SPAN lang=EN>C++应用在何U场合,“组件化”是必不可少的基本要求。?SPAN lang=EN>COM技术虽然在lg化方面比较成熟,但是不具有可UL性,而且对于无须跨语a?SPAN lang=EN>C++开发项目来说过于复杂。因此,C++C需要自己探讨经适用的组件化实用Ҏ?SPAN lang=EN>John Lakos本h从事大型复杂应用软g开发多q_在这斚w的经验无敌,׃来对q个主题q行深入剖析Qƈ且给出实际解x案,毫无疑问是再合适不q的了。虽然这本书q在写作q程中,但是我们有理由对其抱有充分信心。在此我也呼吁本书中文版未来的出版者认真对待此书的译制作Q不要重y?SPAN lang=EN>Large Scale C++》的覆辙?SPAN lang=EN> 

说到COMQ自?SPAN lang=EN>.NET推出Q?SPAN lang=EN>COM的书几乎一夜之间绝了种Q几乎无人再勇于炒这冷饭。但q次出版界的茶实在凉得快了些Q事实上直到今天Q?SPAN lang=EN>COM开发仍然是Windowsq_上应用开发的一个重要方向。特别是在前两年微YWindows核心?SPAN lang=EN>.NET全面转型的左們ֆ险主义的试以失败告l后Q在可见的未来,Windows操作pȝl构建在C/C++?SPAN lang=EN>COM的基之上——这q保了COM?SPAN lang=EN>Windowsq_上的重要C至gl到2011q之后。因此,COM?SPAN lang=EN>ATL?SPAN lang=EN>WTL开发技术在未来几年都还是颇h义的出版题材。特别是q年?SPAN lang=EN>ATL/WTL的发展之快,相比之下Q技术出版在q方面出C一个空白点。此外,开源的Mozilla目提供了一个可UL到所有主^台的COM实现Q这对于C++开发者来说是很具有吸引力的,却一直没有出版资源的xQo人遗憾?SPAN lang=EN> 

C++q年来的一个应用热Ҏ复杂|络应用的开发,ACE在这斚w已经成ؓ来流行的选择Q?SPAN lang=EN>ICE作ؓ目前可用的最先进的高性能中间件品,崛v的势头很猛。这两方面目前都有一些好书,特别是最q出版的?SPAN lang=EN>ACE Programmer?SPAN lang=EN>s Guide》,对于ACE~程入门很有好处。?SPAN lang=EN>ICE 1.3版的手册早已由马l达先生译成中文Q可在网上自p得。不q坦率地_q方面的图书q远q不够,ACE原作?SPAN lang=EN>Doug Schmidt所著的两卷本?SPAN lang=EN>C++ Network Programming》可L和实用性不I?SPAN lang=EN>ICE手册深度和广度都显不够,我们期望q方面能有更好的著作出现?SPAN lang=EN> 

随着多核CPU的普及,q发E序设计成?SPAN lang=EN>C++技术上的一个新热点。这斚w目前的好书几乎没有,不知道这个巨大的I白由何方圣来填补?SPAN lang=EN> 

同样Q网l安全重要性的I前提升?SPAN lang=EN>C++开发提Z很多新的具体要求Q很?SPAN lang=EN>C++老手面一个“再教育”的问题。这斚wMicrosoft Press的?SPAN lang=EN>Writing Safe Code》,O?SPAN lang=EN>Reilly的?SPAN lang=EN>Secure Programming Cookbook for C and C++》,以及最q?SPAN lang=EN>Pearson出版的?SPAN lang=EN>Secure Coding in C and C++》都是不错的参考。不q我发现目前C++开发者ƈ未普遍重视这个问题。也许管理层q需要更加“血淋淋的教训”来刺激一下,才会有革新的动力?SPAN lang=EN> 

在嵌入式斚wQ由于应用复杂度的逐渐提升?SPAN lang=EN>Symbian OS/Windows CE{面向消费的高嵌入式操作系l的q泛应用Q给C++提供了一个广阔的发挥I间。可惜在q方面,真正堪称l典的好书还是凤毛麟角,看来q需要时间和l验的积淀。不q有一本书特别值得一提,北航出版C֎q引q的《嵌入式pȝ的微模块化设计》被国际嵌入式开发领域公推ؓ数年来年度最重要的嵌入式软g开发技术著作,其中含有一些意义深q的创新思想Q非嵌入式开发者也有必要了解此书的大致思想?SPAN lang=EN> 

   

ȝ 

E序设计语言C千计Q能够广为流传的不过几十U,而能够风?SPAN lang=EN>20q的更是屈指可数?SPAN lang=EN>Fortran已经问世50q_仍然是科学计首选,C语言辉煌30q_至今老当益壮?SPAN lang=EN>C++利地度q了自己?SPAN lang=EN>20岁生日,怿属于它的日子q很长很ѝ作?SPAN lang=EN>C++开发者,我们也希望看CU?SPAN lang=EN>C++技术图书不断涌现。历史证明,C++领域内的技术创斎ͼ不但对于C++开发具有重大意义,而且对于整个软g开发技术都h重大意义。我们有理由怿Q在下一个十q里Q以高水q?SPAN lang=EN>C++技术专家和作家Z表的C++技术社能够lؓ软g技术做出突出的贡献?/FONT>

 



늉散步 2006-02-28 17:07 发表评论
]]>
#pragma 预处理指令详解[转蝲]http://www.shnenglu.com/klsmlzm/archive/2006/02/28/3563.html늉散步늉散步Tue, 28 Feb 2006 01:46:00 GMThttp://www.shnenglu.com/klsmlzm/archive/2006/02/28/3563.htmlhttp://www.shnenglu.com/klsmlzm/comments/3563.htmlhttp://www.shnenglu.com/klsmlzm/archive/2006/02/28/3563.html#Feedback0http://www.shnenglu.com/klsmlzm/comments/commentRss/3563.htmlhttp://www.shnenglu.com/klsmlzm/services/trackbacks/3563.html

 

在所有的预处理指令中Q?Pragma 指o可能是最复杂的了Q它的作用是讑֮~译器的状态或者是指示~译器完成一些特定的动作?pragma指oҎ个编译器l出了一个方?在保持与C和C ++语言完全兼容的情况下,l出L或操作系l专有的特征。依据定?~译指示是机器或操作pȝ专有?且对于每个编译器都是不同的?
其格式一般ؓ: #Pragma Para
其中Para 为参敎ͼ下面来看一些常用的参数?


(1)message 参数?Message 参数是我最喜欢的一个参敎ͼ它能够在~译信息输出H?
口中输出相应的信息,q对于源代码信息的控制是非常重要的。其使用Ҏ为:
#Pragma message(“消息文本?
当编译器遇到q条指o时就在编译输出窗口中消息文本打印出来?
当我们在E序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设|这些宏Q此时我们可以用q条指o在编译的时候就q行查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86q个宏可以用下面的方?
#ifdef _X86
#Pragma message(“_X86 macro activated!?
#endif
当我们定义了_X86q个宏以后,应用E序在编译时׃在编译输出窗口里昄“_
X86 macro activated!”。我们就不会因ؓ不记得自己定义的一些特定的宏而抓x腮了
?

(2)另一个用得比较多的pragma参数?SPAN style="COLOR: rgb(255,0,0)">code_seg。格式如Q?
#pragma code_seg( ["section-name"[,"section-class"] ] )
它能够设|程序中函数代码存放的代码段Q当我们开发驱动程序的时候就会用到它?

(3)#pragma once (比较常用Q?
只要在头文g的最开始加入这条指令就能够保证头文件被~译一ơ,q条指o实际上在VC6中就已经有了Q但是考虑到兼Ҏƈ没有太多的用它?

(4)#pragma hdrstop表示预编译头文g到此为止Q后面的头文件不q行预编译。BCB可以预编译头文g以加快链接的速度Q但如果所有头文g都进行预~译又可能占太多盘I间Q所以用这个选项排除一些头文g?
有时单元之间有依赖关p,比如单元A依赖单元BQ所以单元B要先于单元A~译。你可以?pragma startup指定~译优先U,如果使用?pragma package(smart_init) QBCB׃Ҏ优先U的大小先后~译?

(5)#pragma resource "*.dfm"表示?.dfm文g中的资源加入工程?.dfm中包括窗?
外观的定义?

(6)#pragma warning( disable : 4507 34; once : 4385; error : 164 )
{h于:
#pragma warning(disable:4507 34) // 不显C?507?4可告信?
#pragma warning(once:4385) // 4385可告信息仅报告一?
#pragma warning(error:164) // ?64可告信息作Z个错误?
同时q个pragma warning 也支持如下格式:
#pragma warning( push [ ,n ] )
#pragma warning( pop )
q里n代表一个警告等U?1---4)?
#pragma warning( push )保存所有警告信息的现有的警告状态?
#pragma warning( push, n)保存所有警告信息的现有的警告状态,q且把全局警告
{讑֮为n?
#pragma warning( pop )向栈中弹出最后一个警告信息,在入栈和出栈之间所作的
一切改动取消。例如:
#pragma warning( push )
#pragma warning( disable : 4705 )
#pragma warning( disable : 4706 )
#pragma warning( disable : 4707 )
//.......
#pragma warning( pop )
在这D代码的最后,重新保存所有的警告信息(包括4705Q?706?707)?
Q?Q?SPAN style="COLOR: rgb(255,0,0)">pragma comment(...)
该指令将一个注释记录放入一个对象文件或可执行文件中?
常用的lib关键字,可以帮我们连入一个库文g?
(8)用pragma导出dll中的函数

    传统的到?DLL 函数的方法是使用模块定义文g (.def)QVisual C++ 提供了更z方便的ҎQ那是“__declspec()”关键字后面跟“dllexport”,告诉q接去要导出q个函数Q例如:

__declspec(dllexport) int __stdcall MyExportFunction(int iTest);

    把“__declspec(dllexport)”放在函数声明的最前面Q连接生成的 DLL ׃导出函数“_MyExportFunction@4”?/P>

    上面的导出函数的名称也许不是我的希望的,我们希望导出的是原版的“MyExportFunction”。还好,VC 提供了一个预处理指示W?pragma”来指定q接选项 (不仅仅是q一个功能,q有很多指示功能) Q如下:

#pragma comment(linker,"/EXPORT:MyExportFunction=_MyExportFunction@4")

    q下天如h愿了Q)。如果你x定导出的序Q或者只函数导Zؓ序号Q没?EntrynameQ这个预处理指示W?(切地说是连接器) 都能够实玎ͼ看看 MSDN 的语法说明:

/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]

   @ordinal 指定序QNONAME 指定只将函数导出为序PDATA 关键字指定导出项为数据项?/P>

每个~译E序可以?pragma指oȀzLl止该编译程序支持的一些编译功?/SPAN>。例如,对@环优化功能:
#pragma loop_opt(on) // Ȁz?
#pragma loop_opt(off) // l止
有时Q程序中会有些函C使编译器发出你熟知而想忽略的警告,如“Parameter xxx is never used in function xxx”,可以q样Q?
#pragma warn ?00 // Turn off the warning message for warning #100
int insert_record(REC *r)
{ /* function body */ }
#pragma warn +100 // Turn the warning message for warning #100 back on
函数会生一条有唯一特征?00的警告信息,如此可暂时终止该警告?
每个~译器对#pragma的实C同,在一个编译器中有效在别的~译器中几乎无效。可从编译器的文档中查看?/FONT>



늉散步 2006-02-28 09:46 发表评论
]]>
ZTCP/IP的多U程通信及其在远E监控系l中的应?/title><link>http://www.shnenglu.com/klsmlzm/archive/2005/12/16/1830.html</link><dc:creator>늉散步</dc:creator><author>늉散步</author><pubDate>Fri, 16 Dec 2005 09:27:00 GMT</pubDate><guid>http://www.shnenglu.com/klsmlzm/archive/2005/12/16/1830.html</guid><wfw:comment>http://www.shnenglu.com/klsmlzm/comments/1830.html</wfw:comment><comments>http://www.shnenglu.com/klsmlzm/archive/2005/12/16/1830.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/klsmlzm/comments/commentRss/1830.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/klsmlzm/services/trackbacks/1830.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="90%" align=center border=0> <TBODY> <TR> <TD class=font-br style="FONT-WEIGHT: bold; FONT-SIZE: 11pt; COLOR: #336699; LINE-HEIGHT: 150%" align=middle>ZTCP/IP的多U程通信及其在远E监控系l中的应?/TD></TR> <TR> <TD> <HR SIZE=1> </TD> <TR> <TD style="PADDING-BOTTOM: 5pt; COLOR: #919191" align=middle></TD></TR> <TR> <TD style="LINE-HEIGHT: 150%"><BR>  传统的应用程序都是单U程的,卛_E序q行期间Q由单个U程独占CPU的控制权Q负责执行所有Q务。在q种情况下,E序在执行一些比较费时的dӞ无法及时响应用L操作Q媄响了应用E序的实时性能。在监控pȝQ特别是q程监控pȝ中,应用E序往往不但要及时把监控对象的最C息反馈给监视客户Q通过囑Ş昄Q,q要处理本地Zq程Z间的通信以及Ҏ制对象的实时控制{Q务,q时 Q仅仅由单个U程来完成所有Q务,昄无法满监控pȝ的实时性要求。在DOSpȝ下,q些工作可以׃断来完成。而在Windows NT下,中断机制对用h不透明的。ؓ此,可引q多U程机制Q主U程专门负责消息的响应,使程序能够响应命令和其他事g。辅助线E可以用于完成其他比较费时的工作Q如通信、图形显C和后台打印{,q样׃至于影响ȝE的q行?BR><BR>  Q?Windows NT 多线E概q?BR><BR>  Windows NT是一个真正的抢占式多d操作pȝ。在 Windows NT中,启动一个应用程序就是启动该应用E序的一个实例,卌E。进E由一个或多个U程构成Q拥有内存和资源Q但自己不能执行自己Q而是q程中的U程被调度执行。进E至要有一个线E,当创Z个进E时Q就创徏了一个线E,即主U程。主U程可以创徏其他辅助U程Q由ȝE创建的U程又可创徏U程。每个线E都可指定优先Q操作系l根据线E的优先U调度线E的执行?BR><BR>  Windows NT中用多U程的方法有三种Q?BR><BR>  · 使用C多线E库函数Q?BR><BR>  · 使用CreateThread() {Win32函数Q?BR><BR>  · 使用MFCcR?BR><BR>  本文采用W三U方法。在Visual C++5.0 中,MFC应用E序用CWinThread 对象表示U程。基本操作如下:<BR><BR>  · 创徏新线E:调用MFC全局函数AfxBeginThread Q)创徏新线E。AfxBeginThreadQ)启动新线Eƈq回控制Q然后,新线E和调用AfxBeginThreadQ)的线E同时运行。它的返回gؓ指向CWinThread对象的指针;<BR><BR>  · 暂停Q恢复线E:调用CWinThreadcL员函数SuspendThreadQ)暂停U程的运行,调用ResumeThreadQ)成员函数恢复U程的运行;<BR><BR>  · l止U程Q在U程内部可调用全局函数AfxBeginThreadQ)l止U程的运行,否则Q线E执行结束后Q线E自动从U程函数q回q攄E占有的资源?BR><BR>  Q?ZTCP/IP的多U程~程<BR><BR><IMG height=256 src="http://www.jicheng.net.cn/auto_news/images/yd00120801.gif" width=268 align=right>  TCP/IP是lnternet上广泛用的一U协议,可用于异U机之间的互联。TCP/IP协议本n是非常复杂的Q然而在|络~程中,E序员不必考虑TCP/IP的实现细节,只需利用协议的网l编E接口SocketQ亦U套接字Q即可。在 Windows 中,|络~程接口?Windows Socket它包含标准的Berkley Sockets的功能调用的集合Q以及ؓ Windows 所做的一些扩展。TCP/IP协议的应用一般采用客P服务器模式,面向q接的应用调用如图1所C?BR><BR>  Ҏ上述序调用函数建立q接后,通信双方便可交换数据。然而,在调用带*L函数Ӟ操作怼dQ特别是当套接字工作在同步阻塞模式(Blocking ModeQ时。这ӞE序无法响应M消息。ؓ了避免出现这U情况,本文引进辅助U程。在执行含有可能d的函数的dӞ动态创建新的线E,专门处理该Q务。主U程把Q务交l辅助线E后Q不再对辅助U程加以控制与调度。本文分别针对connectQ)、acceptQ)、receiveQ)、sendQ){可能阻塞的函数创徏了相应的U程Q如?所C?BR><BR><IMG height=139 src="http://www.jicheng.net.cn/auto_news/images/yd00120802.gif" width=323 align=left>  多线E编E常常还要考虑U程间的通信。线E间的通信可以采用全局变量、指针参数和文g映射{方式。本文采用指针参数方式。在调用AfxBeginThreadQ)函数Ӟ通过传递指针参数的方式在主U程与辅助线E间通信?BR><BR>  AfxBeginThreadQ)函数的用法如下:<BR><BR>  CWinThread*AfxBeginThread?QAFXQTHREADPROC pfnThreadprocQ?BR><BR>  LPVOID pParamQ?BR><BR>  int nPriority=THREADQPRIORITYQNORMALQ<BR><BR>  UINT nStackSixe=0Q?BR><BR>  DWORD dwCreateFlags=0Q?BR><BR>  LPSECURITYQATTRIBUTES pSecurityAttrs=NULLQ;<BR><BR>  参数pfnThreadProc指定U程函数必d下定义:<BR><BR>  UINT MyControllingFunction(LPVOID pParamQ; <BR><BR>  参数pParam 是调用线E传递给U程函数pfThreadProc的参敎ͼ<BR><BR>  其他参数一般只需采用~省倹{?BR><BR>  指针参数通信方式是通过参数pParam在线E间通信的,它可为指向Q何数据类型的指针。本文中Q定义了一个名叫EXCHANGEQINFO的结构如下:<BR><BR>  typedef struct<BR><BR>  { SOCKET sServerSocketQ<BR><BR>  SOCKET ?pcCoientSocketQ<BR><BR>  SOCKADDRQIN ?pClientAddrQ<BR><BR>  BOOL *pbConnectedQ?BR><BR>  unsigned char *pucBuffer;<BR><BR>  int *pnMessageLen;<BR><BR>  } EXCHANGEQINFOQ?BR><BR>  在需要通信Ӟ先声明一个结构变量,再把变量的指针作为pParam参数Q调用AfxBeginThreadQ(AFXQTHREADPROCQ CSocketThreadQ:WaitFor ConnectThreadQ(LPVOIDQ& mQExchangeinfoQ函数即可?BR><BR>  Z利用面向对象技术编E所h的模块性强、便于修攏V可UL性好{优点,本文q把?中的U程装为父cMؓCWinThread的自定义cCSocketThread中。还自定义了一个叫CSocketComm的新c,装了一些函敎ͼ如CreateSocket、ConnectToServer、WaitForClient、ReadMessage、SendMessage{,q些函数屏蔽了面向连接的通信E序的实现细节,如创建、连接、发送和接收{,在这些函数里Q动态创助线E?BR><BR>  下面以CSocketCommcM的等待客戯接请求的函数WaitForClientQ)ZQ注释说明多U程~程的具体细节?BR><BR>  BOOL CSocketComm::WaitForClient?BR><BR>  { <BR><BR>  if(mQbConnected)return? TRUE );<BR><BR>  Q/配置bind函数的参数x务器的套接字地址l构<BR><BR>  SOCKADDRQIN Addr?<BR><BR>  memset(QAddr,0,sizeof(SOCKADDRQIN));<BR><BR>  AddrQsinQfamily=AFQINET;<BR><BR>  ADDRQSINQport= htonl?mQnPort); <BR><BR>  AddrQsinQaddrQsQaddr?= htonl(INADDRQANY); <BR><BR>  Q/套接字地址l构赋予套接字(l定Q,以指定本地半相关<BR><BR>  int nReturnValue;<BR><BR>  nReturnValue =::bind? mQsSserverSocket,( LPSOCKADDR)&Addr,sizeof (SOCKADDRQIN ));?<BR><BR>  if?nReturnValue == SOCKETQERROR) ?returu? FALSE );<BR><BR>  Q/配置传给WaitForConnectThreadU程函数的参数mQExchangeinfo<BR><BR>  mQExchangeinfoQsServerSocket = mQserverSocket;?BR><BR>  mQExchangeinfoQpsClientSocket = QmQsClientSocket;?BR><BR>  mQExchangeinfoQpClientAddr = QmQlientAddr;?BR><BR>  mQExchangeinfoQpbConnected = QmQbConnected;?BR><BR>  Q/以mQExchangeinfo的指针ؓ参数调用WaitforConnectThreadU程{待客户端连?BR><BR>  AfxBeginThread?(AFXQTHREADPROC)CSocketThread::<BR><BR>  WaitForConnectThread,?LPVOID)?QmQExchanginfo); <BR><BR>  returi? TRUE )<BR><BR>  }<BR><BR>  Q/{待q接U程<BR><BR>  UINT CSocketThread::WaitForConnectThread?LPVOIDpParam)?BR><BR>  {<BR><BR>  EXCHANGEQINFO?pExchangelnfoQ?EXCHANGEQINFO*) pParam;?BR><BR>  int nReturnValue, nClientAddrSize= Sizeof? SOCKADDRQIN);<BR><BR>  Q/侦听q接<BR><BR>  nReturnValue=:: listen?pExchangelnfo Q>sServerSocket, 1); <BR><BR>  if? nReturnValue == SOCKETQERROR )return?0);?BR><BR>  Q/d调用acceptQ直x客户q接h<BR><BR>  *pExchangelnfoQ>psClitentSocket=:: accept?pExchangelnfoQ>sServerSocket,??LPSOCKADDR)?pEchangelnfo Q>pClientAddr,&nClientAddrSize); <BR><BR>  if?( *pExchangelnfoQ>psClitentSocket)!= INVALIDQSOCKET)?BR><BR>  Q/通过pExchangelnfo的指针在U程间通信<BR><BR>  * pExchangelnfoQ>pbConnected TRUE;<BR><BR>  return? 0 );<BR><BR>?BR><BR>  Q?应用实例Q高层协议的设计<BR><BR><IMG height=138 src="http://www.jicheng.net.cn/auto_news/images/yd00120803.gif" width=327 align=right>  在电厂和늫中,Z保证安全工作Q保护系l必不可。保护系l的甉|供应通常使用两种方式。一般情况下Q用交电pȝ对保护系l进行供电;当交电pȝ出现故障~立即使用后备的蓄甉|pȝ对保护系l进行供cؓ了对蓄电池系l进行监控和理Q以保证蓄电池在关键时刻能正常工作,设计了在Windows NT环境下具有远E通讯功能和动态h机界面的蓄电池远E监控系l?。该pȝp甉|理、充甉|控制、母U绝~在U检、声光报警、系l组态、远E通信{子pȝl成Q实现对蓄电池/充电机智能化q程理和控ӞҎ个系l的q行状态进行实时监控,h多媒体报警、事件处理、动态数据库、趋势画面和动态画面显C、操作提前提醒等功能。系l框囑֦?所C。在q程通信模块中,q程监控机需把监控客L操作命o及时传给本地机,本地机根据命令控制充甉|Q之按照一定的方式工作Q而本地机需定时向远E监控机反馈实时的充甉|状态信息。它们之间的通信是基于TCP/IP的广域网通信Q而且Q我们引q了多线E机制以保证pȝh良好的实时性?BR><BR>  下面以其中的充电机控制系lؓ例谈谈如何用CSocketCommc进行远E通信。ؓ单v见,假定本地Zq程监控Z间通信的信息仅有下面三U类型:<BR><BR>  ·本地机接收到该命令后Q控制充甉|按照E_模式q行Q输出电压ؓ电压l定|<BR><BR>  ·本地机接收到该命令后Q控制充甉|按照Ex定时模式q行Q输出电ؓ甉|l定|<BR><BR>  ·本地机向q程监控机发送充甉|的实时状态数据(包括输出电压、输出电、状态指C和故障cd指示Q?BR><BR>  在基于TCP/IP的面向连接的|络通信中,客户与服务器之间传送的是有序可靠的字节(Byte StreamQ,所以程序员有必要在传输层TCP上定义自q高层协议Q设计l构Q将字节变成有意义的信息。在CSocketCommcM由AssembleMessage()函数把数据组合成一定的帧结构。l构为:<BR><BR> <DIV align=center><IMG height=22 src="http://www.jicheng.net.cn/auto_news/images/yd00120804.gif" width=263></DIV><BR><BR>  其中Qؓ帧v始标志,Qؓ帧终l标?BR><BR>  对应的结构定义如下:<BR><BR>typedef struct<BR><BR>{ int MessageType;?Q/信息cd<BR><BR>int ChargerNo;?Q/充电机编?BR><BR>int DataNo;?Q/数据cd<BR><BR>float Data;?Q/数据<BR><BR>} MessageStruct;?BR><BR>  需要通信Ӟ先声明一?MessageStruct变量Q根据信息内容对各成员变量赋|传给 AssembleMessage()函数l合成Q再调用SendMessage()函数发送给接受斏V接受方接到数据后,Ҏ据内容的解释Q是由CsocketCommcM的AnalyzeMessage()函数完成的。AnalyzeMessage()函数q回一?MessageStruct变量。应用程序就可根据它的各成员变量控制充电机或动态显C充甉|的状态?BR><BR>  MQ把多线E机制引q通信Q有利于提高应用E序的实时性,充分利用pȝ资源。对于大型的工程应用来说Q不同的U程完成不同的Q务,也有利于提高E序的模块化Q便于维护和扩展。本文给Z一U在Windows NT下基于TCP/IP协议的多U程通信的基本方法,Ҏ该方法进行修改和扩充Q便可设计出W合具体应用的高质量的多U程通信E序?/TD></TR></TBODY></TABLE><img src ="http://www.shnenglu.com/klsmlzm/aggbug/1830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/klsmlzm/" target="_blank">늉散步</a> 2005-12-16 17:27 <a href="http://www.shnenglu.com/klsmlzm/archive/2005/12/16/1830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>std::string ?char cd的相互{?/title><link>http://www.shnenglu.com/klsmlzm/archive/2005/12/15/1794.html</link><dc:creator>늉散步</dc:creator><author>늉散步</author><pubDate>Thu, 15 Dec 2005 07:27:00 GMT</pubDate><guid>http://www.shnenglu.com/klsmlzm/archive/2005/12/15/1794.html</guid><wfw:comment>http://www.shnenglu.com/klsmlzm/comments/1794.html</wfw:comment><comments>http://www.shnenglu.com/klsmlzm/archive/2005/12/15/1794.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.shnenglu.com/klsmlzm/comments/commentRss/1794.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/klsmlzm/services/trackbacks/1794.html</trackback:ping><description><![CDATA[<P>  //string 转换?char ?BR>  char* str = strdup ( SendData.strSql.c_str() );<BR>  cout << str << endl;</P> <P>  char 转换?string ?BR>  char* str = "char 转换?string ?;<BR>  SendData.strSql = str;<BR><BR>//SendData.strSql 为std::string?/P><img src ="http://www.shnenglu.com/klsmlzm/aggbug/1794.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/klsmlzm/" target="_blank">늉散步</a> 2005-12-15 15:27 <a href="http://www.shnenglu.com/klsmlzm/archive/2005/12/15/1794.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转蝲:学习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一部分除了modelQ模块)Q在 ICE 1.3中文手册中都有描q?

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

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

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

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

基础知识

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Q注QICE 1.3的中文手册上没有“模块”这一部分Q模块来l织一l相关的语句是ؓ了解军_字冲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而没有必要编译整个模块)?

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

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

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

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

cd 取D?/TH> 大小Q单位: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除了所有位为零的字W?/TD> 变长

用户定义的类?/H3>

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

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

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

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

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

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

    Slice 不允许定义空的枚举?

  • l构

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

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

    sequence<Fruit> FruitPlatter;
    

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

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

    sequence<FruitPlatter> FruitBanquet;
    

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

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

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

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

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

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

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

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

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

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

      q种技术用了下面的惯用手法:

      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可能会把不止一个元素放入序列。ؓ可选值增加一个专用的Slice 成分可以U正q个问题。但可选值ƈ非那么常用,不值得为它增加一U专门的语言Ҏ(我们看刎ͼ你还可以用类层次来徏立可选字D)?

  • 词典

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

    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你无需让键成ؓ值的一部分?

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

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

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

      dictionary<string, string> WeekdaysEnglishToGerman;
      

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

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

      • 整型Qbyte、short、int、long、boolQ以及枚丄型)

      • string

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

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

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

  • 帔R定义与直接量

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

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

    • float 或double

    • string

    下面有一些例子:

    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有一些小的例外)Q?

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

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

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

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

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

        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的范围内;否则~译器会发出诊断警告?

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

        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的串直接量会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 串在许多~程语言里不存在

接口、操作,以及异常

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



늉散步 2005-12-13 12:00 发表评论
]]>
转蝲:学习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达同志的翻译给我们的学习带来了方便?

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; 

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

	try {
	//初始化Ice run time Qargc和argv是run time命o参数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?背一下单词)?
		Ice::ObjectPtr object = new PrinterI;

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

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

		//最后,我们调用waitForShutdown?
		//q个Ҏ挂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 会等待Q何还在运行的操作调用完成?
		//此外Q?destroy q会保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。你可以把这些代码放在一个辅助类里,然后无需再ؓ它费心了QIce 提供了这L辅助c,叫作Ice::ApplicationQ参?10.3.1 节) 。就实际的应用代码而言Q服务器只有几行代码Q六行代码定义PrinterI c,再加上三2 行代码实例化一个PrinterI 对象Qƈ向对象适配器注册它?

dL代码

文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位于接口和类的承树的根部(接口的基c)?
		 Ice::ObjectPrx base 
		=ic->stringToProxy(	"SimplePrinter:default -p 10000");

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

		//现在Q我们在我们的地址I间里有了一个激zȝ代理Q?
		//可以调用printString ҎQ?
		//把n誉已久的 "Hello World!" 串传l它?
		//服务器会在它的终端上打印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客户会打印一条出错消息。例如,如果我们没有先启动服务器p行客P我们会得刎ͼ

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

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



늉散步 2005-12-13 11:58 发表评论
]]>
ȫþվ| þþۺ㽶ۺ| þøƬ| þþƷӰѿ | þ˳ƷCAOPOREN| 99þþƷձһ| ƷëٸAVѾþ| þ91ƷۺϹҳ| þþƷһ| ݺ޾þþþþۺ| þù| AŮAVۺϾþþ| ɫۺϾþ֮ۺϾþ| 2021þþƷѹۿ| ˾þۺϳ| þþƷҹһ | Ʒþþþ| 99þ777ɫ| þþþƷSmվ| þ97㽶| þAV˳׽| 99þþƷҹһ| þùֻоƷ| ޹ƷþSM| ԻԻ˿þþ| ŷպ˾Ʒþþѿ| þǿdŮվ| 99þùۺϾƷ鶹| ܻƺ۵վþmimiɫ| ޹Ʒ۲ӰԺþ | þþþ| ٸþ| ƷȾþav| ɫþþþþþС˵| ɫۺϾþ| þwww˳_Ƭ| Ʒþþþav| ĻƷþ| bƷþþþþþ| þþþ99ƷƬֱ| 99ƷѾþþþþ |