A Little Fool

Fool For Free.

博客园 首页 新随笔 联系 订阅 管理
  164 Posts :: 0 Stories :: 66 Comments :: 0 Trackbacks

置顶随笔 #

eplaylity 翻译的:

SDL游戏教程第一课 课程基础

SDL游戏教程第二课 坐标与块复制

SDL游戏教程第三课 消息(Events)

SDL游戏教程第四课 井字游戏

SDL游戏教程第五课 动画

 

 附带的SDL教程:

SDL 图像

 

 

 

我自己翻译的:

SDL游戏教程第六课 实体 (Entities)

 

SDL游戏教程第七课 地图 (Maps)

 

 

附带的SDL教程:

SDL 声音库 (SoundBank)

 

 

 

 

 

 

 

posted @ 2009-03-21 15:45 Henry Read 阅读(680) 评论(2) 编辑

[C/C++ 书籍合集]C/C++ eBooks Collection (updating...)

 

[Linux 书籍合集] Linux eBooks collection 

 

[PYTHON 书籍合集]PYTHON eBooks Colletion (updating....)

 

 

[Java 电子书合集]Java eBooks Collection (Updating....)

 


[PHP 书籍合集]PHP eBooks Colletion (updating...)

 

[JavaScript书籍合集]JavaScript eBooks Colletion


 [Ajax 电子书合集] Ajax eBooks Colletion

 

[Lisp/Scheme书籍合集]Lisp And Scheme eBooks Collection

 

[Perl书籍合集]Perl eBooks Collection

 

计算机网络(Computer Networks)相关书 下载


posted @ 2009-01-21 00:46 Henry Read 阅读(539) 评论(0) 编辑

2010年10月14日 #

我自己翻译的一篇文章,希望能对你有所帮助。

原文链接:http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

进化游戏的层次结构

  - 用组件来重构你的游戏实体

直到最近几年,游戏程序员一直使用深层次结构的类表示游戏实体。现在的潮流开始逐渐从深层次的结构,到仅仅是把游戏实体对象作为聚合组件的方向转变。这篇文章解释了这些转变意味着什么,并且探讨了用这种方式带来的的好处和实际情况中的使用。我将会描述我个人的一些经验,怎样在大项目中实现这个系统,当然也包括怎样去卖你的方案给别的程序员和经理。

 

游戏实体

不同的游戏有不同的需求,就像游戏实体应该需要什么一样。但是在大多数的游戏里,实体的概念是十分的相似的。一个游戏实体就是一个在游戏世界里的对象,通常这个对象对于玩家来说是可见的,并且通常它还能四处移动。

一些实体的例子:

l        子弹

l        小轿车

l        坦克

l        手榴弹

l       

l        英雄

l        行人

l        外星人

l        喷气式飞行器

l        医疗包

l        石头

实体通常可以做很多事情。下面是一些事情你也许想要实体去做的:

l        运行一个脚本

l        移动

l        表现的像个死板的东西

l        发射粒子

l        播放特定的声音

l        能被玩家放在背包里

l        能被玩家穿上

l        爆炸

l        表现的有磁性的

l        被玩家瞄准

l        沿着一条路径走

l        动画

传统的深层次结构

传统的表示一组实体集的方式就像是在分解我们想要去表的实体集。这样做通常开始的意图是好的,但是随着游戏的开发进度这些东西经常要变动尤其是当一个游戏引擎被不同的游戏重新使用时。我们通常最后的设计出如 B-1那样,但是实际上的类层次结构比图中节点还要多。

 

B-1

随着开发的进行,我们通常需要增加很多不同的功能到实体上。对象必须要么封装自己封装功能,要么从有那个功能的别的对象那里继承过来。经常性的功能被加载接近类层次结构的根节点上,比如说CEntity类。这样做有一个好处,就是所有派生类都能有那些功能。但是不好的地方是会被这些类带来相关的开销。

即使是非常简单的对象比如石头或者是手榴弹,到最后会有大量的额外功能(和相关的成员变量,或者是不必要执行的成员函数)。传统的游戏对象层次结构经常到最后要创建一个被称作团迹”(胖球)(the blob)的东西。胖球是经典的反模式之一,表现为一个巨大的单类(或者是有大量的分支在类的层次结构上),拥有大量的复杂的互相交织的功能。

当胖球反模式经常在对象层次结构的根节点附近出现,它也就显现在叶子节点上了(译注:因为叶子节点是继承自根的)。最有可能的候选者因该是表示玩家的类。由于游戏通常是针对单一角色而编写的程序,因此表示角色的对象经常有大量的功能。这经常是实现为在一个类里比如CPlayer类,有大量的成员函数。

实现这么多功能在层次结构的根节点附近的结果就是给叶对象大量不需要功能的过重包袱。不管怎么样,用相反的实现方法,在叶子节点上实现大量的功能,同样是不幸的结果。功能现在被分解了,所以只有专门为那个对象编程的特定功能才能使用它。程序员经常复制一样的代码到已经被不同的对象实现的镜子函数里。最终,需要重新组织类的层次结构这种肮脏的重构来移动和组合功能。

先来一个例子吧,有一个对象在在物理作用下表现为刚体的功能。不是所有的对象需要做到这样。你可以在图B-1里看到的那样,我们仅仅让CrockCGrenade类从CRigid类派生。如果我们想要将此功能应用到车子上会发生什么呢?你不的不把CRigid类移到层次结构的上面去,让它变得更像我们以前看到的根部的重型胖子模式,所有的的功能都被串成一条类的窄链子从其他最先开始继承的类开始起。

 

聚合组件

组件方式,现在越来越得到现在的游戏开发的认可,是一种把不同的功能分开放到不同的独立于其他组件的组件上的方法。传统的对象层次结构被免除了,并且一个对象现在被创建为为一个独立的组件的聚合(积聚物)。

每个对象现在只有它需要的功能了。任何不同的新共嫩被实现为增加一个组件。

一个由聚合组件组成的对象系统能有3种方式实现,可以被看成将胖球对象层次结构转移到一个组合对象上去的不同阶段。下面将介绍一下这3个阶段。

 

对象作为组织胖球

一种通常重构胖球对象的方法是将它的功能分散到不同的子对象上去,然后被第一个对象所引用。最终,父系的胖球对象被一系列的指向其他对象的指针代替,最终胖球对象的成员函数编程了这些子对象上函数的接口函数。

这也许事实上是一个合理的解决方案,如果你的游戏对象里的功能在一个合适小的范围内,或者如果时间是有限的。你可以简单实现任意的对象聚集,通过允许一些子对象为空(通给一个NULL指针给它们)。假设没有太多的子对象,那么这仍然允许你有一个轻型的没有实现一个管理此对象的组合框架的伪组合对象的优势。

不足之处是,这仍然在本质上是一个胖球。所有的功能人然被封装在一个大对象里。这不像是你完全的分解胖球对象到纯的子对象那样,所以你仍然遗留了一些重要的开销,仍然会让你轻型的对象变重。你仍然有不断检查所有空指针,以便看看是否需要更新的开销。

 

对象作为组件容器

下一个阶段是分解每个组件(上一节例子里的“子对象”)成共享一个公共的基类的对象,因此我们可以存储一个对象的列表在对象里。

这是一个过度的解决方法,我们仍然有表示游戏实体的根“对象”。不管怎样,它应该是一个合理的解决方案,或者确实是在实践中是可行的方案,如果一大部分的代码库中需要这种概念的游戏对象作为具体对象的话。

你的游戏对象然后变成了一个接口对象,充当了在你游戏里的遗留代码之间桥的作用,并且还是新系统的组合对象。如果时间允许,你最终将会把游戏实体对象作为整体式对象的概念消除掉。相反,访问对象越来越直接的通过它所在的组件了。最终,你能够将其转换到纯聚合了。

 

对象作为纯聚合

在最终的布置图里,一个对象简单是各个部分的和。图B-2显示了一个方案,每个对象都是由许多不同的组件组成的。这里没有所谓的“游戏实体对象”。每一列在图标中都表示同一组件,每一行因此都能表示一个对象。组件自己也可以看成是和组成它们的对象是独立的。

 

B-2

实践经验

我第一个用组件实现的对象的组合系统是我在Neversoft公司做Tony Hawk系列游戏的时候做的。我们的游戏对象系统一直伴随着三个连续发布的游戏而发展,指导我们有了一个游戏对象的层次结构来重组我先前提到的胖球反模式。它遭受着所有同样的问题:对象倾向于重量级的。对象有不必要的数据和功能。有时不必要的功能让游戏变慢。功能有时在不同树的分支上重复。

我在sweng-gamedev的邮件列表里听说过这个关于“基于对象的组件”系统的新式发明。我觉得那听起来是一个好主意。我于是开始重新组织代码,两年以后把它完成了。

为什这么长的时间?因为,首先我们在以每年一个的速度艰苦的做出Tony Hawk游戏,所以只有很少的时间让我们投入到重构上。第二,我错误的计算了问题的规模。一个三年时间长的代码群已经包含大量的代码。大量的代码一年一年的逐渐变成了某种不灵活的代码。由于代码依赖于游戏对象成为游戏对象,尤其是的某些游戏对象。那说明了有大量的工作要去做,才能使得所有的东西都已组件方式工作。

 

预期的阻力

我第一遇到的问题就是怎样试着解释这个系统给其他的程序员。如果你不是特别的熟悉对象组合和聚合的事情,那么会被认为是无意的,不必要的复杂,不必要的多余工作,让你受备受打击。程序员已经在传统系统的对象层次结构上工作了很多年,已经非常习惯那种工作方式了。它们甚至变得擅长于那种方式来,能解决那些出现的问题了。

把这个方案卖给经理也是一个困难。你需要能够用平实的语言准确的描述,这个方案怎样能够让游戏完成的更快。下面是一段的因该说的话:

“当我们加入新的特性到游戏里时,那会花费很长的时间去完成,将会导致很BUGS。如果我们采用这种新的组件对象的东西,它能让我们加入新的特性更快,会有更少的BUGS

而我采用是一种悄悄的方式。我首先和一些程序员单独讨论这个主意,最后说服他们这是一个好主意。我然后实现了通用组件的基本框架,并且还实现了游戏对象功能的很小的一部分作为组件。

我然后把这些成果呈现给剩下的程序员。他们有一些疑惑和抵触,但是由于它已经实现了并且它在那里工作不是一个大的争议。

 

缓慢的进展

当框架被链接上了,从静态的层次结构到对象组合的方便性显现的很缓慢。那是一个吃力不讨好的工作,即使你花了很多小时,很多天将代码重构成一些看起来像样的东西,但其和被替换的代码没有什么两样。而且,我们还在做这个事情的时候,我们仍然在为下一个游戏实现新的功能。

在早些时候,我们撞上了重构我们最大的类滑雪者类的问题。由于它包含有大量的功能,它甚至在一段时间几乎无法重构一小点。事实上,它也无法被重构除非其他在游戏里的对象系统已经服从了组件方式了。话又说回来,其他那些对象系统也不容易被组件化,除非滑雪者已经是一个组件了。

这里的解决方案是创建一个“胖球组件”。这是一个单独的巨型组件,封装了大量滑雪者类的功能。少量的其他胖球组件也需要被用在别的地方。我们最终硬是将对象系统塞进了组件里。当这个事情到位了,胖球组件能被逐级的重构成更多的原子组件。

 

结果

一开始重构的结果不是那么明显。但是随着时间的推移,代码变得越来越清晰并且变得更容易维护,功能都被封装到分散的组件里了。程序员开始用更少的时间创建新类型的对象,仅仅简单的组合一些组件然后再加一个新的。

我们创建了一个数据驱动的对象创建系统,因此整个新类型的对象都能被设计人员创造。这被证明对于快速创建和配置新类型的对象是非常有价值的。

最终程序员开始(以不同的速度)接受组件化系统了。并且他们变得非常熟练的擅长通过组件来增加新的功能了。通用的接口和严格的封装使得BUGS减少了,代码也更容易阅读,更容易维护和重用。

 

实现细节

给每一个组件一个通用的接口意味着继承自同一个带虚函数的基类。这会带来额外的开销。但不要因为这一点而使你反对这种方法,节约的开销和对象的简单性相比是不不重要的。

由于每个组件都有一个公共的接口,非常容易的就可以增加额外的调试成员函数给每个组件。这使得增加一个能导出组件的组合对象的可读信息的诊断器对象更容易了。然后,这可以被进化成一个复杂功能的远程调试工具,总能够得到几乎所有类型的游戏对象的最新信息。这也许在传统的层次结构的系统里去实现和维护是十分的令人厌恶的。

理想情况下,组件应该互相不知道到对方。不管怎么样,在现实世界里,总是有特定组件间的依赖关系。性能问题,也决定了组件应该能够快速的访问其他组件。开始的时候,我们让所有组件的引用都是通过组件管理器的,但是当开始时只用了5%CPU时间,我们允许组件存贮指向其他对象的指针,并且直接调用在其他组件里的成员函数。

在组件里,怎样组合对象的顺序是非常重要的。在我们一开始的系统里,我们把组件作为链表存储在一个容器对象里。每个组件有一个更新函数,每个对象每次迭代组件列表时被调用。

由于对象创建是数据驱动的,那样会造成麻烦的,如果在链表里的组件不是期望的顺序的话。如果一个对象更新物理相关内容在动画相关内容之前,但是另外一个对象更新动画相关内容在物理相关内容之前,这样他们就会互相失去同步。互相依赖关系像这样的必须找出来,然后在代码里定义强制规则。

 

结尾

用组件把从胖球风格的对象层次结构转变成组合对象结构是我所做的最好的决定之一。开始的结果是让人失望的,它花费了太多时间去重构现有的代码。不管怎么样,最后的结果是非常值得,轻型的,灵活的,健壮,和可重用的代码。

posted @ 2010-10-14 21:26 Henry Read 阅读(263) 评论(4) 编辑

2010年7月19日 #

作者:钱义力
北京工业大学软件学院 2002 级研

下载源代 码

  很早就想做一个类似QQ一样的聊天程序,苦于一直没有时间,再加上觉得网络多点通信比较难做,所以这个想法就搁在一旁。最近二个月学校放假闲着无聊看 了一些Tcp/ip,多线程的书,再加上以前的一点C++和VC的基础,就着手做了起来,共化了17天完成了这个程序。它包括服务器端程序 NetMsgServer和客户端程序NetMsgClient。通过编程还发现原始的socket(像send,recv等)命令比VC封装好的 CScoket速度要快。怎么说呢,程序不小,有3000多行的代码,错误和垃圾代码肯定也不少了,毕竟水平有限,大家看了不要扔鸡蛋就谢谢了。

一、说明
  本程序采用tcp/ip socket多线程编程,并对一些重要的同步操作做了超时控制,以减少等待的时间,像连接服务器,等待对方接收文件等。基本功能跟QQ类似,能进行多点的 聊天和点对点的文件传送。这种编程的优势在于传送的数据不会丢失,而且用户上线下线能即时反应出来。唯一的遗憾是界面做的太滥,本人对界面编程一窍不通, 暂且还只能在局域网内使用,因为没有增加可以通过代理服务器的功能。

二、大概通信流程



1、NetMsgServer 服务器端
  它采用了两个线程,其中一个线程处理各个客户端的连接请求(accept),另一个在客户端请求连接成功后处理接收到的命令并返回信息,包括用户注 册、登陆、下线、生成在线用户列表、查询修改某个在线用户的信息等。

2、NetMsgClient客户端
  每个NetMsgClient客户端既是信息服务器端,又是信息客户端,所以能实现多点通信。
2.1
  通过注册来获得用户号码。发送两条命令:"REGT\t\n",再发送一个用户资料的数据结构。注册成功服务器返回一个id号给用户,否则返回一个错 误代码。

send(m_dcSocketClient,(char *)&userInf,sizeof(userInf),0);//发送用户资料

其中:

USER_INF userInf;
//用户信息的结构
typedef struct
{
long id;
char nickname[20];
char sex[10];
int age;
char address[50];
char password[20];
}USER_INF,*LPUSER_INF;
2.2
  开启第一个线程登陆服务器,端口是4000。以下1000表示我的id号,发送"USER 1000" 和"PASS password"命令要求登陆服务器。

2.3
  如果登陆成功,就发送"LIST \t\n"命令到服务器端,取得在线用户的列表,并显示在列表框内。在线列表以结构数组的形势传送。
recv(m_dcSocketClient,(char *)(m_onlineUser),sizeof(m_onlineUser),0);

其中:

ONLINEUSER_INF m_onlineUser[MAX_ONLINE_NUM]; //在线用户数组
typedef struct
{
long id;
char nickname[20];
char ip[16];
SOCKET s;
}ONLINEUSER_INF,*LPONLINEUSER_INF;
2.4
  然后开启第二个线程创建消息服务器端,接受各个客户端的连接请求,端口是4001。
while(TRUE)
{
int sockLen=sizeof(inetAddr);
if((sAccept=accept(sListen,(SOCKADDR*)&inetAddr,&sockLen))==INVA LID_SOCKET)
{
AfxMessageBox("错误:accept failed in threadMsg");
return 1;
}

AfxBeginThread(threadRecvMsgServer,(LPVOID)sAccept);
}
2.5
  如果接收到连接就开启第三个线程接受对方的信息。
recv(acceptSocket,buff,sizeof(buff),0)

  假如我是1000这个用户,接受到"chat 1001\t\n"指令,说明是1001这个用户想和我聊天,如果我的聊天人数太多就拒绝1001的聊天请求。

sprintf(buff,"%d\t\n",REJECT_CHAT_REQ);send(acceptSocket,buff,sizeof(buff),0);

如果接受他的请求,就发送确认信息。

sprintf(buff,"%d\t\n",ACCEPT_CHAT_REQ);send(acceptSocket,buff,sizeof(buff),0);
接下来就可以通信了。

2.6
  如果双方还要求传送文件,就开启第4个线程,端口是4002,只是点对点的通信,如果1000想法送文件给1001,文件发送方建立文件服务器端,然 后由消息通讯线路(即上面的acceptSocket)发送"File anc.avi\t\n"命令到对方消息通讯线路上,让1001连接1000的file文件服务器。1001连接到1000的file服务器上后,发送确 认命令决定是不是接收文件,如果接收就可以开始传送文件。

2.7
  假定我是1000这个用户,1001已经连接到我的机器,并和我聊天,这时如果我还想和1002聊天,就开启第5个线程发送"chat 1000\t\n"到1002的信息服务器端(端口4001,每个netmsg客户端都有信息服务器端),如果还想和1003聊天,就开启第6个线程发送 命令"chat 1000\t\n"到1003的信息服务器端请求连接,这样每个客户端都可以实现多点通讯。

QQ:54476167
posted @ 2010-07-19 22:45 Henry Read 阅读(253) 评论(1) 编辑

http://linode.codingnow.com/cgi-bin/mt/mt-tb.cgi/213

 

前段时间思考了 Windows 下应用程序最合适的实现模型。写了这么一篇 blog 在 Windows 下使用 Timer 驱动游戏

我想,Windows 有 Windows 的哲学,Windows 平台下的应用程序,也有他的理念。关于 Windows 编程的书,我比较喜欢 Charles Petzold 的那本:《Windows 程序设计》(还有另一本是《WIndows 核心编程》,在第 5 版的 3.2 节中就提到 Windows 编程的难点在于“别调用我,我会调用您”以及“行动迅速”。

以前,我不十分理解 Windows 为什么把大量的任务放在消息循环中被动的调用,慢慢的我有点理解了。这就是 Windows 。

网络编程我一直是顺着 BSD socket 来学习和使用的,所以 Windows 下写 winsock 程序也一直没有改变习惯。这两天突然对这个做了下反思,按照 Windows 的理念来写 socket 程序应该是怎样的形式?查了下 msdn 后,发现了一个以前被我忽略掉的 api —— WSAAsyncSelect 。

以前粗读 mfc 的源码时,仿佛见过 CSocket 用这个来实现。当时没有太在意;也听不同的几个朋友跟我简单介绍过它,同样没有放在心上。直到今天,自己突然有兴趣了,才仔细研究了一下。

从今天的眼光来看,winsock 并不是一个很好的设计。在 tcp/ip 已经一统天下来看,winsock 的许多设计是蹩脚且多余的。不过,当我们把自己代入 winsock 设计的那个年代,再结合 windows 自己的理念来看。就会发现许多合理之处。

WSAAsyncSelect 就是提供了一个最适合 Windows 自己运作模型的工作方式。它可以把 socket 的消息映射到线程的消息循环中。这符合:“别调用我,我会调用您”的 Windows 哲学。

具体的用法是多说无益,msdn 已经讲的很清楚了

通过 WSAAsyncSelect 设置,线程消息循环将在指定的事件发生后,得到相应的消息。WSAGETSELECTEVENT(lParam) 可以用来得到网络事件本身,而 wParam 则被用来传递 socket 的 handle 。然后,就可以主动调用 socket 函数来处理这些事件了。我觉得这比 select 的模型更适合 Windows 应用程序。

而 windows 的应用程序的主体永远只需要一个简单的循环来处理和分发消息就够了。

今天我本想 google 一下,看有没有专门讲解 windows 网络编程的书。发现只有一本《Windows网络编程技术》,读了一下 china-pub 上的书评后,倒了胃口,便不想买了,还是读 msdn 吧。

posted @ 2010-07-19 18:18 Henry Read 阅读(263) 评论(0) 编辑

2010年7月14日 #

今天去面试一家游戏公司,笔试题有道叫做 设计并实现一个Singleton基类。以前没有认真考虑过这个问题,转载了一篇。

原文地址:http://blog.csdn.net/Blue_Light/archive/2008/07/13/2646266.aspx

 

 

 

在创建型模式中,有一种设计模式“Singleton”。该模式的意图是,保证一个类仅有一个实例,并提供一个访问它的全局访问点。在GOF的指导下,我 们经常写一些Singleton类。每个类很类似。

   以下代码描述了一个Singleton的基类及使用方法:

template <class T>

class AllocUsingNew

{

public:

    static T* Create()

    {

       return new T;

    }

 

    static void Destroy(T *p)

    {

       delete p;

    }

};

 

template <class T>

class AllocUsingStatic

{

public:

    static T* Create()

    {

       static T t;

       return new (&t)T;

    }

 

    static void Destroy(T *p)

    {

       p->~T();

    }

};

 

template <class T,template <class> class AllocPolicy = AllocUsingStatic>

class Singleton

{

public:

    static T* Instance()

    {

       if (NULL == m_pThis)

       {

           m_pThis = AllocPolicy<T>::Create();

           assert(m_pThis);

           m_pThis->Initialize();

       }

       return m_pThis;

    }

 

    static void Destroy()

    {

       if (m_pThis)

       {

           m_pThis->Finalize();

           AllocPolicy<T>::Destroy(m_pThis);

           m_pThis = NULL;

       }

    }

 

    void Initialize()

    {

    }

 

    void Finalize()

    {

    }

 

protected:

    Singleton(){}

    ~Singleton(){}

private:

    Singleton(const Singleton&);

    Singleton& operator = (const Singleton&);

    friend class AllocPolicy<T>;

private:

    static T * m_pThis;

};

 

template <class T,template <class> class AllocPolicy>

T* Singleton<T,AllocPolicy>::m_pThis = NULL;

 

class MySingleton : public Singleton<MySingleton,AllocUsingNew>

{

public:

    void SetValue(int value)

    {

       m_value = value;

    }

 

    void print()

    {

       cout << m_value << endl;

    }

 

    void Initialize()

    {

       m_value = 1000;

    }

 

private:

    int m_value;

};

 

 

int _tmain(int argc, _TCHAR* argv[])

{

    MySingleton::Instance()->print();

    MySingleton::Destroy();

 

    system("pause");

 

    return 0;

}

posted @ 2010-07-14 22:05 Henry Read 阅读(171) 评论(2) 编辑

2010年7月3日 #

VC6 STLport-5.1.4 编译,安装

1. 开启命令行窗口,建立VC环境, 执行 %MSVCDir%\VC98\Bin\VCVARS32.BAT
2. 切换到 %STLport-5.1.4%\build\lib,执行 configure -c msvc6 -clean, 进行编译配置。其中:
     -c 选择编译器
     -clean 完成后清除 build configuration files
 更多选项参数使用命令 configure --help 查看
3. 执行 nmake /fmsvc.mak 或者 nmake /fmsvc.mak install,后者在编译完成后拷贝生成的library至%STLport-5.1.4%\lib目录下。建议使用 install 参数。
4. 打开VC6,在Tools->Options->Directories中,添加include files路径:%STLport-5.1.4%\stlport,添加library files路径:%STLport-5.1.4%\lib,调整这两个添加的路径至第一路径位置。
5. 修改工程选项:Project->Settings...->C/C++中,Category选择Code Generation,然后在use run-time library中选择Debug Multithreaded。(如果是release版本,选择Multithreaded;如果想用动态链接,则要先编译动态链接版本的 STLport,再在这儿选择相应的DLL)

VC6 STLport-4.6.2 编译,安装【%STLport-4.6.2% 表示 其路径,比如 C:\STLPORT 等】
1. /*****
     a.修改....\VC98\Bin中的VCVARS32.BAT文件,找到
          set INCLUDE=%MSVCDir%\ATL\INCLUDE;%MSVCDir%\INCLUDE;%MSVCDir%\MFC\INCLUDE;%INCLUDE%
          set LIB=%MSVCDir%\LIB;%MSVCDir%\MFC\LIB;%LIB%
        这两句,加上STLPort的路径,修改成如下:
          set INCLUDE=%STLport-4.6.2%\stlport;%MSVCDir%\ATL\INCLUDE;%MSVCDir%\INCLUDE;%MSVCDir%\MFC\INCLUDE;%INCLUDE%
         set LIB=%STLport-4.6.2%\lib;%MSVCDir%\LIB;%MSVCDir%\MFC\LIB;%LIB%
 
     (C:\STLport\lib目前还不存在,但不用着急,编译完stlport就有了)
    ****/

2. 开启命令行窗口,建立VC环境, 执行 %Microsoft Visual Studio%\VC98\Bin\VCVARS32.BAT
3. nmake -f vc6.mak clean all      (vc6还可以选择支持unicode的vc6-unicode.mak文件)
4. 配置VC:
    点击vc的tools-options-Directories,
       选择Include files,加入%STLport-4.6.2%\STLPORT,并调到最前面
       选择Library files,加入%STLport-4.6.2%\LIB,并调到最前面 

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

 VC6(SP6)+STLPort4.6.2安装全攻略


首先,我对VC/c++几乎没有经验,STL也是刚开始学。为了用stlport,瞎忙呼了大半天,也是刚刚装好。为了避免自己或者别人安 装stlport时再走弯路,特记录下这段经历。由于我很菜,即使安装完毕,仍有很多不明之处,所以下面的文档如果有错误,请您批评指出。文中还有一些疑 问,希望学深入之后自己能解答,也欢迎网友帮我解答。



step by step, Now:


1.安装VC6,打补丁sp6
 (下载地址http://msdn.microsoft.com/vstudio/downloads/updates/sp/vs6/sp6/default.aspx)


2.推荐安装一个visual assist for VC6,这是个好东东。它使得编辑环境更加好用。
  (有个下载地址http://www.vcer.net/download.jsp?id=1042       http://www.vcer.net/upload/2004/04/1042.zip 不知道失效没有)


3.到www.stlport.org下载STLPort。我下载 的是stlport4.6.2
  (http://www.stlport.org/archive/STLport-4.6.2.tar.gz)


4.未使用stlport之前,先看看VC的stl库的表现。
  作一个最简单的工程,编一个cpp
    #include <vector>
    using namespace std;
    int main()
    {
        vector<int> v;
        v.push_back(0);
        return 0;
    }
   这个程序编译能通过,把鼠标放到vector和push_back上,右键到其定义处(goto the Definition of ...),在弹出的窗口,(注意到这些定义中std是小写的字串)。选中一个进入定义文件,可以看出引用的 是....\VC98\Include\VECTOR文件。这个目录下还有LIST等等,这是VC6自带的STL实现。据说比较烂,没用过我不了解:)
  
   但是下面这个程序就编译不过了。
 #include <vector>
 #include <deque>
 
 using namespace std;
 int main()
 {
  const int arraySize = 7;
  int ia[arraySize] = {0, 1, 2, 3, 4, 5, 6};
  vector<int> v(ia, ia+arraySize);
  //v.push_back(0);
  deque<int> d(ia, ia+arraySize);
  return 0;
 }
 原因应该是VC6的deque不支持这样的构造吧。但是这个程序在用gcc的Dev-c++下编译就没有问 题。
 
 好了,保存我们的工程,可以猜想,如果stlport安装成功之后,应该是可以顺利编译的。


5.把下载的stlport压缩包解压,我假设解压到C:\STLport(紧挨着C:\STLport的子目 录是stlport的src,doc,stlport等目录)


6.编译stlport
  (1) 设置环境变量,使得环境变量PATH中包含C:\Program Files\Microsoft Visual Studio\VC98\Bin
      (当然也可以不设置,如果你愿意不厌其烦地打这个目录名)
  (2) 打开一个dos窗口(运行cmd)
  (3)  运行 ....\VC98\Bin中的VCVARS32.BAT:
    
     /*****
     a.修改....\VC98\Bin中的VCVARS32.BAT文件,找到
          set INCLUDE=%MSVCDir%\ATL\INCLUDE;%MSVCDir%\INCLUDE;%MSVCDir%\MFC\INCLUDE;%INCLUDE%
          set LIB=%MSVCDir%\LIB;%MSVCDir%\MFC\LIB;%LIB%
        这两句,加上STLPort的路径,修改成如下:
          set INCLUDE=C:\STLport\stlport;%MSVCDir%\ATL\INCLUDE;%MSVCDir%\INCLUDE;%MSVCDir%\MFC\INCLUDE;%INCLUDE%
         set LIB=C:\STLport\lib;%MSVCDir%\LIB;%MSVCDir%\MFC\LIB;%LIB%
 
     (C:\STLport\lib目前还不存在,但不用着急,编译完stlport就有了)
 
    注意:第(3)-a步骤修改VCVARS32.BAT这个文件的内容完全没有必要,我是看某些文档上这么写的,但后来试了几次,改不改这个文件都没有关 系!所以不改算了。(这步骤注销!)
    ****/
 
    b.在dos窗口中运行....\VC98\Bin下这个文件VCVARS32.BAT  (必须!!!)
 
  (4) 在同一个dos窗口中!进入C:\STLport\src目录运行
      nmake -f vc6.mak clean all
      (问题,vc6还可以选择支持unicode的vc6-unicode.mak文件,但vc中unicode如何用,我还不了解:( )
  
    编译需要一点时间,完成之后,你可以选择运行 nmake -f vc6.mak install。
    注:install任务是可选的,看stlport的INSTALL文档:       
    [quote]
        "install" target works on most platforms.
     On Win32, it does the following :
      - copies STLport headers in "stlport" subdirectory of your compiler's INCLUDE directory;
      - copies STLport .lib files in your compiler's LIB directory;
      - copies STLport DLLs to Windows system directory so they can be found at runtime.
      [/quote]
     
      dums(stlport论坛上的高手)建议一般不要用nmake install,我也强烈建议不要运行这个nmake install!!!如果你想vc的stl和STLPort的stl共存,那么这个install任务就更加不要执行!!!
     
      (如果你还是要运行nmake install,并且运行有错误,则再运行一次VCVARS32.BAT先)
     
      /**
      问题:有个安装文档中写到完成之后要修改C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\SYSINCL.DAT,我没有试,怎么修改?有什么用?
      **/
     
7.配置vc
   进入VC,编译前面那个有错的cpp,发现还是有同样的编译错误。
   (即使修改了VCVARS32.BAT,加上stlport的路径,也没有用!似乎这个文件不能把include和lib加入。这也是我说为什么不用修改 VCVARS32.BAT的原因,不明白这个文件在运行vc时的作用,请您指正:) )
  
   点击vc的tools-options-Directories,
     选择Include files,加入C:\STLPORT\STLPORT,并调到最前面
     选择Library files,加入C:\STLPORT\LIB,并调到最前面
   编译工程,呵呵,应该通过了吧。同样的,为了验证我们用的是stlport的STL库,把鼠标放到程序中vector和push_back上,右键到其定 义处(goto the Definition of ...),在弹出的窗口,(注意到这些定义中STL是大写的字 串了)。选中一个进入定义文件,可以看出引用的是C:\STLport\stlport\stl\_vector.h了。
   (如果有问题,试着Build-Clean清除掉缓存)
  


引申:
   现在只是能基本的使用stlport,unicode版本的编译没有试。另外stlport本身也有较复杂的配置,能进行优化,静态链接等配置。我还没用 到那个程度,不过有点提示,如果想进行配置,请看STLport的config文件 (stlport/stl_user_config.h 和 stlport/stl/_site_config.h)其中的注释告诉我们怎么作。
posted @ 2010-07-03 22:25 Henry Read 阅读(156) 评论(0) 编辑

2010年5月10日 #

/*
 ********************************************************************************
 *
 * 作者:祝飞
 * 邮件:zhufei@wawton.com
 * MSN: zhufei@wawton.com
 * 出处:http://zhufei1980.spaces.live.com/blog/cns!131FD0729BCEF27B!121.entry
 *
 * 本系列文章采用类BSD协议发布:
 *     无论修改与否,你都可以进行任何目的的转发,甚至于直接销售,只需要满足以下条件:
 *     1. 包含作者信息(作者、邮件、MSN、出处、协议)
 *     2. 未获得授权情况下,请勿使用作者信息进行任何目的的推广活动
 * 违反协议的情况下,作者保留所有权利。
 *
 ********************************************************************************
 */

总概
    跨平台C++程序开发,顾名思义,一份相同的代码,在不同的平台编译,在不同的平台运行。
    所谓的跨平台,一般意义上指Windows和Unix-like平台;
    需要跨平台的程序,一般从Unix-like平台跨越到Windows平台,需要更多平台的展示及更低廉的解决方案;
    而从计算机的方展史来看,先有Unix-like系统,后有Windows平台,Windows平台的许多系统接口参考了Unix-like系统接口;
    所以,现有的跨平台解决方案,一般都偏向Unix接口;
    要进行跨平台开发,建议先打好Unix-like系统的C/C++编程基础。

C++ 循序渐进学习之书籍推荐
 
目录
    1.  跨 平台C++程序开发系列之一 开发工具选择
    2.  跨 平台C++程序开发系列之二 MPC多平台编译工程文件生成工具,附实例
    3.  跨 平台C++程序开发系列之三 CppUnit自动测试工具,附实例
    4.  跨 平台C++程序开发系列之四 Doxygen接口文档生成,附实例
    5.  跨 平台C++程序开发系列之五 ACE跨平台工具库引介
    6.  跨 平台C++程序开发系列之六 DLL/so动态库开发基础,附实例
    7.  跨 平台C++程序开发系列之七 DLL/so动态库开发进阶,附实例
    8.  跨 平台C++程序开发系列之八 DLL/so动态库开发高阶之COM_CORBA本质,附实例
    9.  跨 平台C++程序开发系列之九 多厂家支持数据库操作接口
    10. 跨 平台C++程序开发系列之十 GUI开发工具的选择
    11. 跨 平台C++程序开发系列之十一 C与C++的选择与平衡
    12. 跨 平台C++程序开发系列之十二 基于管理和预分配池的多进程多线程服务器端程序方案
    13. 跨 平台C++程序开发系列之十三 开发架构模式的选择,CMM与XP的混合
    14. 跨 平台C++程序开发系列之十四 解放思想,选择适合自己的开发之路

 

 

 

 

以上转载的文章仅供参考,我认为有不少“偏见”,要怎么走还是要看自己选择和现实的情况。

posted @ 2010-05-10 15:16 Henry Read 阅读(264) 评论(0) 编辑

2010年3月21日 #

摘要: 【来源:TSTC文档中心】   计算机自从其诞生之日起,它的主要任务就是进行各种各样的科学计算。文档处理,数据处理,图像处理,硬件设计, 软件设计等等,都可以抽象为两大类:数值计算与非数值计算。作为研究计算机科学技术的人员,我们大都对计算数学对整个计算机科学的重要性有一些了解。但是 数学对我们这些专业的研究和应用人员究竟有多大的用处呢?我们先来看一下下面的一个流程图: 上图揭示了利用计算机解决科学...阅读全文
posted @ 2010-03-21 10:28 Henry Read 阅读(241) 评论(0) 编辑

2010年2月21日 #

摘要: (一) 首先声明,这个是给业余初学者看的,高手们就算了,可以来挑挑错。 看来有不少业余作曲爱好者啊,当然我也是其中之一。我们业余人士写作主要凭感觉,但 是感觉也不是随便来的。有很多写作的规律,还有禁忌,算是定式吧,我由于一开始不知道,所以走了很多弯路。我希望能和大家分享我的一些经验,如果不打算系 统地学习乐理的话,少走一些弯路。 首先,来说说音阶,因为这里有很多术语回头会用到,所以必须从这里说起...阅读全文
posted @ 2010-02-21 18:18 Henry Read 阅读(104) 评论(0) 编辑

2010年1月30日 #

摘要: 1.DancingWind NEHE中文教程 NEHE是十分不错的opengl教程,由浅入深,配合实例讲解。而DancingWind本着一颗分享的心,制成中文版。看官不必一课一课按顺序看但每 一课都应该认真看,中文苦手者可配合英文版观 看……各位可以在他网站下 载,或者告诉我(zwqxin.com) 以代其传给你(汗)。此外DancingWind还整合了几种OPENGL...阅读全文
posted @ 2010-01-30 22:47 Henry Read 阅读(282) 评论(0) 编辑

摘要: 因为工作的原因,自己现在也没有太多时间专注于游戏开发。这里将以前收集的一些OpenGL教程网站罗列出来,与喜欢OpenGL、游戏开发的朋友一起分 享。当然还有一些好的教程网站没有包含在里面,欢迎大家补充,标题的“Top Ten”也完全是为了吸引大家的眼球。不过我想对于大多数人包括我自己来说,最主要的并不是缺乏学习的资料,而是缺乏一种持之以恒、坚持不懈的精神。1.http:...阅读全文
posted @ 2010-01-30 22:43 Henry Read 阅读(287) 评论(0) 编辑