avatar
Today is 星期天
2010年09月5日

搜索结果 分类目录: C/C++

2010年05月30日

[转]游戏UI解决方案汇总

由 晨笛 — 分类目录: C/C++评论暂缺

1.CEGUI
   
CEGUI是老牌的开源界面库了,最新版本是0.7.1,完全免费,也是Ogre官方推荐使用的界面库,Ogre1.6及以前的版本,都是内置支持的。使用它的商业游戏也非常多,比如天龙八部,火炬之光,仙剑四等。这也就证明CEGUI确实强大,可以完全达到商业应用级别,而且相关资料非常丰富,至少不用担心某个功能无法实现,因为你能碰到的问题,网上基本都有解决方案,经过这些大作的证明,就不要怀疑了:)。
    但是功能强大是有代价的,就是它太庞大、复杂了,上手很困难。这些大作没有一个不修改CEGUI的,也就是说要真正用起来,或者说要用的好,还是要做点事的。那需要做多少事呢?不清楚。

2. Ogre SDKTray
   
从Ogre1.7开始就不再内置支持CEGUI了,转而使用Ogre自己的SDKTray,“tray”是在ogre的overlay和material的基础上实现的,使用很容易理解和使用,但目前它还只是个半成品,无法应用到商业游戏中。

3.QuickGUI
    最新版本10.1,专为Ogre写的UI库,支持Ogre1.7,比起CEGUI来说,小巧了很多。
但是很遗憾,至今还有没有编辑器(作者的Blog上说正在开发,但是还没有发布),要靠手动编写xml文件,囧啊~~Ogre社区里从来没有人推荐使用这个。我只是简单看了下,感觉像是作者练手的项目(个人观点)。

4.Hikari
    Hikari可以让你使用Flash制作界面,最新版本0.3,完全免费,大家知道Flash动画是非常流行的,如果将Flash应用到游戏中,一定很拉风!Hikari就实现了这个功能,通过Flash.ocx将swf渲染成Ogre的Texture,然后你就可以任意操作这个Texture了,正是因为如此,Hikari支持Flash的所有版本,不存在兼容性问题。因为Flash本身就支持多国语言,所以中文显示也没有问题。可以把界面开发的大部分内容放到Flash那边,从而使客户端简洁很多(简单就是美啊)。
    但是Hikari最致命的问题的效率太低,它使用的是Flash的ocx,先将动画内容渲染到DC上,然后拷到Texture中,所以很慢,而且慢的是第二步,使得Flash优秀的脏矩形优势无法发挥,根本无法应用到商业游戏中。我做了个动画,30张图片随机飘动,1023×768的窗口,使Flash占满,Release版只能跑到15帧(集成显卡),这还没有显示任何文字呢:(

5.Scaleform
    Scaleform跟Hikari的作用是一样的,都是用Flash来做游戏界面,不同的是Scaleform非常牛X,它的效率很高,可以说是最强游戏界面解决方案了!而且对亚洲语言显示和输入都完美支持。目前最新版本是3.2,据说4.0将支持Actionscript 3.0, 并全方位支持3D UI。超过600款游戏使用Scaleform做界面,比如超大作StarCraft II,Crysis,Fable II,Civilization IV,Halo Wars,Princes of Persia,Mess Effect 2,Prototype,Resistance 2,Splinter Cell等。
    心动了吧,可惜Scaleform是收费的,而且授权费相当的高,3.X版的目标售价是15万美金。如果你不在乎钱的话,这绝对是不二之选,在乎钱的话,这是二B之选。PS:有不少商业引擎已经将Scaleform集成进去了,比如Gamebryo,Unreal3等,如果你不用Ogre,买了商业引擎也爽了~~

6.ogreSwf/vektrix
    Hikari效率太低,Scaleform太贵,ogreSwf/vektrix就是出来解决这个矛盾的。ogreSwf跟Scaleform一样都由开源的gameSwf发展起来,Scaleform开始商业化,ogreswf继续开源,后来ogreswf项目停掉了。2010年ogreSwf的作者重起了该项目,在原来的基础上改进并改名为vektrix,2010年4月发布了新的demo,可能是SourceForge的原因,我下的demo文件无法解压,又觉得vektrix目前还无法达到Scaleform的高度,所以后来就没有再试了。

7.Awesomium
    Awesomium的功能有点类似Hikari,只不过它是将网页渲染成Texture,而且效率方面也做的比较好。Awesomium 采用了目前业界速度最快的浏览器内核webkit和v8,其实是把Chrome内核嵌入到了里面,同时还很好地支持flash,可以通过javascript使游戏和网页交互。该项目最初也是开源的,后来商业化了,但是不太贵,最便宜的版本只要400多美金。
    Awesomium的效率之所以高,估计也是脏矩形方面做的好,我把上面那个动画嵌到网页中,用Awesomium打开,帧数马上就下来了,所以还是不能做UI,但是游戏中的帮助页面则可以考虑用这个。Awesomium也不方便根据网页内的内容做半透明效果,也就是网页中部分半透明很难实现,全透明,也就是镂空效果则可以通过模板实现。

8.MYGUI
      MyGUI最新版本3.0.1,是俄罗斯人写的,要么没有注释,要么注释是俄文的,而且相关的资料实在是太缺乏了,虽然小修改一下可以支持中文显示,但是效果太差了,根本不能用,更别说多种文字,多种效果了,目前也没有什么商业游戏是用这个库做的。
      但我最终选择了这个UI库。
      就像MYGUI的介绍一样“MyGUI – fast, simple and flexible GUI.”这确实是一个,高效,轻便,灵活的库。首先它的设计很好,所以即使没有注释,也不难理解。换肤的设计避免了CEGUI里的很多中间层,使用要简单很多,资源文件的管理也要清爽(清楚+爽)一些。没有使用ogre的overlay,用底层直接画了,效率比CEGUI要高。LayoutEdit,ImageSetEdit等比CEGUI的要好用的多,CEGUI的工具经常当掉- -。中文显示可以模仿CEGUI去做,我已经完全实现,效率并不低,完全可以接受。
      载入layout文件后返回一个窗口的vector,你可以自己写一个类似BaseLayout的类去管理,然后像MYGUI一样大量用C++委托做回调函数,就可以把各个Dialog分开去写,就像写MFC的Dialog一样,这一点做的实在太好了。如果再学一点CEGUI,把Lua脚本集成进去,载入layout文件时把窗口注册到lua中,这样就可以在脚本里写逻辑了,客户端-UI-脚本,很清晰。
     为什么没有商业游戏使用MYGUI呢?MYGUI比较稳定的版本2.2.3是09年10月份发布的,是少要1年才能有游戏出来,火炬之光是09年11月上市的,在开发的时候MYGUI还很不完善,以后一定会有不少游戏使用MYGUI:)

2010年04月29日

链接静态MFC库时要注意

由 晨笛 — 分类目录: C/C++评论暂缺

今天需要给公司同事做个办公用的小软件,由于项目简单,根据经验做就行,也就没做太多规划,窗口系统就用MFC来做了。不想在发行时附带VC内部的几个DLL,就把项目设置为use MFC in a static library,结果出现了一些错误,在网上搜索得到以下解决办法:

链接错误

nafxcw.lib(afxmem.obj) :error LNK2005: “void * __cdecl operator new(unsigned int)”(??2@YAPAXI@Z) already defined in LIBCMT.lib(new.obj)

这是因为VC的编译器在编译程序时有两个习惯:
a、在从头开始编译时,将源文件名按字母排序后,依次处理。
b、一边编译一边决定需要哪些缺省库。

C运行时库(CRT)和Microsoft基础类库(MFC)的链接顺序有误。CRT库对new、delete、DllMain函数使用弱外部链接,MFC库包含new、delete、DllMain函数,这些函数要求先链接MFC库,然后再链接CRT库。

强制链接器按照正确的顺序链接库。
Project ->setting ->Link : category ->Input
Ignore libraries: nafxcw.lib ; libcmt.lib
Object/library modules:nafxcw.lib ; libcmt.lib
注意顺序,前者为MFC静态链接库,后者为C运行时库。

使用MFC库时,务必先链接它们,然后再链接CRT库。这可以通过确保项目中的每个文件都首先包含 Msdev\Mfc\Include\Afx.h 来完成。直接包含(#include <Afx.h>)或间接包含(#include <Stdafx.h>)都可以。Afx.h包含文件会通过使用#pragma comment (lib,”<libname>”)指令来强制采用库的正确顺序。

连接时警告

warning LNK4089: all references to “SHELL32.dll” discarded by /OPT:REF

链接器工具警告 LNK4089/OPT:REF 已丢弃所有对“动态链接库”的引用,链接器放弃了引用 dynamic-link library 中的导出的所有封装函数。

如果代码中未使用的函数引用链接器已放弃的DLL导出,也会出现此警告。用#pragma comment(linker,”/ignore:4089)可以取消警告。

在project->settings->linking->projects options中加上/OPT:NOREF 也可以。

2009年08月26日

关于Boost之编译参数说明

由 晨笛 — 分类目录: C/C++评论暂缺


bjam --build-type=complete --with-regex --toolset=msvc-9.0 stage
bjam --build-type=complete --with-system --toolset=msvc-9.0 stage
bjam --build-type=complete --with-thread --toolset=msvc-9.0 stage
bjam --build-type=complete --with-date_time --toolset=msvc-9.0 stage

stage/install :stage表示只生成库(dll和lib),install还会生成包含头文件的include目录。本人推荐使用 stage,因为install生成的这个include目录实际就是boost安装包解压缩后的boost目录(E:\SDK \boost_1_39_0\boost,只比include目录多几个非hpp文件,都很小),所以可以直接使用,而且不同的IDE都可以使用同一套头文件,这样既节省编译时间,也节省硬盘空间。

toolset :指定编译器,可选的如borland、gcc、msvc(VC6)、msvc-9.0(VS2008)等。

without/with :选择不编译/编译哪些库。本人不需要编译python库,所以排除之,可以根据各人需要选择,默认是全部编译。但是需要注意,如果选择编译python的话,是需要python语言支持的,应该到python官方主页http://www.python.org下载安装。

stagedir/prefix :stage时使用stagedir,install时使用prefix,表示编译生成文件的路径。推荐给不同的IDE指定不同的目录,如VS2008对应的是E:\SDK\boost_1_39_0\vc9\lib,VC6对应的是E:\SDK\boost_1_39_0 \vc6\lib,否则都生成到一个目录下面,难以管理。如果使用了install参数,那么还将生成头文件目录,vc9对应的就是E:\SDK \boost_1_39_0\vc9\include\boost-1_39\boost,vc6类似(光这路径都这样累赘,还是使用stage好)。

build-dir :编译生成的中间文件的路径。这个本人这里没用到,默认就在根目录(E:\SDK\boost_1_39_0)下,目录名为bin.v2,等编译完成后可将这个目录全部删除(没用了),所以不需要去设置。

link :生成动态链接库/静态链接库。生成动态链接库需使用shared方式,生成静态链接库需使用static方式。这里需要注意的是,static 方式下,最终生成的很多静态链接库大小都在几兆、几十兆,甚至接近百兆。这么大的库我们一般是不会采用静态链接方式的,所以这些库不推荐以static方式编译(without掉);如果已经编译了赶快删,肯定没用,否则将占用近1G的硬盘空间。以下是巨型库黑名单:wave、graph、math、 regex、test、program_options、serialization、signals。

runtime-link :动态/静态链接C/C++运行时库。同样有shared和static两种方式,这样runtime-link和link一共可以产生4种组合方式。虽然它和link属性没有直接关系,但我们习惯上,一个工程如果用动态链接那么所有库都用动态链接,如果用静态链接那么所有库都用静态链接。所以这样其实只需要编译2种组合即可,即link=shared runtime-link=shared和link=static runtime-link=static。

threading :单/多线程编译。一般都写多线程程序,当然要指定multi方式了;如果需要编写单线程程序,那么还需要编译单线程库,可以使用single方式。

debug/release :编译debug/release版本。一般都是程序的debug版本对应库的debug版本,所以两个都编译。

2009年07月2日

用vc9编译qt4.3.1

由 晨笛 — 分类目录: C/C++评论暂缺

qt4.3.1与vc9是兼容的。

编译过程如下:
C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat
set QMAKESPEC=win32-msvc2005
set QTDIR=C:\Qt_433
cd C:\Qt_433
configure
nmake

2009年06月5日

基于Tiny C Compiler的C语言脚本混合编程方法

由 晨笛 — 分类目录: C/C++评论暂缺

TCC简要介绍:

TCC 最有趣的特性是可以用 UNIX 系统上常见的 #!/usr/bin/tcc 的方式来执行 ANSI C 语言写就的源程序,省略掉了在命令行上进行编译和链接的步骤,而可以直接运行 C 语言写就的源程序。这样就能做到像任何一种其它的脚本语言比如 Perl 或者是 Python 一样,显著的加快开发步调。可以像编写 Shell 脚本一样的使用 C 语言,随便想一想都觉得是一件奇妙的事情。但是 TCC 还有一些其它的特性呢!

    * TCC 的体积非常小,全部源代码打包压缩以后不到 200 K 字节大小,编译后的 tcc 可执行程序不过 80 K 字节大小。这意味着我们几乎可以在任何场合使用 TCC 提供给我们的编写 C 语言脚本的能力。这其中当然包括硬盘空间十分紧张的环境,比如嵌入式系统和启动软盘等等。
    * 在给 TCC 的源程序中可以使用任何在给 GCC 的源程序中可以使用的动态链接库。TCC 不仅支持标准的 ANSI C 语言,而且也支持 ISO C99 标准和一部分来自于 GCC 的对 C 语言所做的扩展。
    * TCC 直接生成经过部分优化的 X86 机器代码。并不需要生成任何虚拟机的二进制代码。据 TCC 作者提供的数据,TCC 的编译速度比 GNU C 编译器在不做任何代码优化工作(gcc -O0)的时候都要快。当然啦,要是让 GCC 做代码优化的话,那么编译速度就更加比不上 TCC 喽。
    * Libtcc 库能够让用户将TCC作为作为动态代码生成的后端,在libtcc.h中有API的说明,libtcc_test.c是使用libtcc的简单例子。 Libtcc包含了这样一种思想,用户可以将程序包含在字符串中,然后直接编译,接下来就可以存取全局符号(函数和变量)。

生成LIBTCC:
       由于libtcc是基于linux的,为了能够生成window下的动态连接库,我们先要使用mingw/msys编译,然后用下面的语句生成dll。为了方便msvc使用,还需要再生成lib库用于链接。整个步骤如下:
1) 生成DLL
gcc -O2 -shared -Wall -Wl,–export-all-symbols -mpreferred-stack-boundary=2 -march=i386 -falign-functions=0 -fno-strict-aliasing -DTCC_TARGET_PE -DLIBTCC -o libtcc.dll tcc.c
2) 生成def
pexports libtcc.dll | sed “s/^_//” > libtcc.def

3) 从def生成lib
lib /machine:i386 /def:libtcc.def
    由于c语言编程需要头文件和库,我们也需要在发布程序的时候带上include目录和lib目录,然后在主程序中指定该路径。

TCC和主程序的配合:
       在我们的程序中,主要把固定的逻辑放在主程序中,而将变化的东西放在tcc脚本中。该程序的基本流程如下:
       按照用户的输入参数打开截包,按照指定的类型将每一个数据报合适的数组片断传给用户写的tcc程序,由tcc程序将处理后的数据传给主函数,由主函数进一步处理,比如写入文件中。
注意到我们需要处理的可能是rtp包,也可能是没有rtp头的包,在输出的时候,有些码流也需要加入额外的处理,比如h261和h263需要调用主程序中的函数进行sbit,ebit的拼接;比如h263+的简单处理,比如h264的流头的添加,比如音频的直接输出。所以我们在主程序和tcc程序间不光要传递变量,还需要传递函数。
下面是大概的代码框架和解释。

主程序:——————————————————————————-
TCCState *s;
创建新的tcc状态
    s = tcc_new();
    if (!s) {
        fprintf(stderr, “Could not create tcc state\n”);
        exit(1);
    }
       添加路径:
       tcc_add_include_path(s,fullinc);
       tcc_add_library_path(s,fulllib);

       设置输出方式为内存:
       tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
       编译一个文件到tcc中(其实是读文件到缓冲区,然后调用了tcc_compile_string)
       tcc_compile_file(s,fullpath);
       将变量和函数符号加入到tcc环境中去,这样在tcc中就可以直接使用这些符号
       tcc_add_symbol(s, “encodeflag”, (unsigned long)&encodeflag);
       tcc_add_symbol(s,”f”,(unsigned long )&f);
       tcc_add_symbol(s,”Enter_H263Decode”,(unsigned long)&Enter_H263Decode);
       tcc_add_symbol(s,”writeFile”,(unsigned long)&writeFile);

       做所有的重定位工作,在tcc_get_symbol之前必须调用
       tcc_relocate(s);
       获取tcc中的函数和变量符号
    tcc_get_symbol(s, &val, “Process”);
    Process = (pf_Process)val;
       tcc_get_symbol(s,&val,”withRtp”);
       withRtp=(int)(*(int *)val);
       tcc_get_symbol(s,&val,”offset”);
       offset=(int)(*(int *)val);
       循环处理每一个数据包
       while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0)
{
       。。。
调用tcc中的处理函数
       Process(&pkt_data[offset],totallen);
}

清理tcc环境
tcc_delete(s);

TCC程序 ——————————————————————————
#include <stdio.h>
#include <stdlib.h>

int withRtp=1;
int offset=54;
unsigned char zero[2]={0,0};
unsigned char h264head[4]={0,0,0,1};

extern FILE *f;
extern unsigned char encodeflag;
extern int writeFile(unsigned char *buf,int len);

int Process(unsigned char *pt,int len)
{
       if(encodeflag==0 ||encodeflag==1)
       {/*h261或者h263*/
              if((pt[0])&0×7==0)
              {
                     Enter_H263Decode(len,pt,1);
              }
              else
              {
                     Enter_H263Decode(len,pt,0);
              }                  
       }
       else if(encodeflag==2)
       {/*h263+*/
        if((pt[0]==0×04) && (pt[1]==0×00))
        {
                  writeFile(zero,2);
                  writeFile(&pt[2],len-2);
           }
        else if((pt[0]==0×00) && (pt[1]==0×00))
        {
                  writeFile(&pt[2],len-2);               
           }
        else
        {
               printf(“not correct 263+ format\n”);
        }
                    
       }
       else if(encodeflag==3)  
       {/*raw data*/
              fwrite(pt,1,len,f);
       }
       else if(encodeflag==4)
       {/*mp3*/
              if(pt[0]==0xff && pt[1]==0xfb)
              {
                     writeFile(&pt[4],len-4);
              }
              else
              {
                     printf(“not a mp3 header,%02X %02X\n”,pt[0],pt[1]);
              }                  
       }
       else if(encodeflag==5)
       {/*h264*/
              writeFile(h264head,4);
              writeFile(pt,len);
       }
       else
       {
              ;
       }   
       return 0;
}

从上面的例子可以看出,使用tcc,可以很容易的处理数组,毕竟,采用其他脚本语言的话,比如lua,perl等,要想处理数组,要想容易的进行位运算,还是很麻烦的,而且,c语言毕竟是大多数人熟悉的语言,使用起来很方便。

2008年12月8日

在WINDOWS下编译TBB库

由 晨笛 — 分类目录: C/C++3 条评论

    为了便于在各平台间移植,TBB库用常见的C++模板和编码样式开发,由GNU MAKE工具构建,兼容多种C++编译器,比如gcc、MS VC++、Intel C++ Compiler等。
    在WINDOWS环境下编译TBB库,需要的工具有:

    1、能生成WINDOWS程序的C++编译器,比如Intel C++ Compiler或MS VC++,推举使用Intel C++ Compiler(windows版)。我使用的编译环境是Windows 2003 Server sp2 + Intel Cpp Compiler(Win IA32) v10.1.020 + Visual Studio.Net 2008(VC9)。

    2、GNU MAKE工具。在WINDOWS平台下运行这类工具,略为麻烦,需要搭建一个既能兼容GNU MAKE又能执行Windows程序的环境,常见的Windows下的UNIX模拟环境,比如MinGW、Cygwin等可以满足这一要求。Gygwin运行Windwos程序不是很方便,而且与TBB库的MAKE脚本搭配得不是很好(需要修改一些地方才能通过编译),这里就只介绍如何在MinGW环境中构建TBB库。
    下面先对MinGW做个简单介绍:

    MinGW即Minimalistic GNU for Windows 的缩写,是一个建立在GCC和binutils 项目上的编译器系统。和其它GCC的移植版相比,MinGW可以说是最接近Win32的,因为MinGW几乎支持所有的Win32API,这也是MinGW的特色之一。MinGW所连接的程序,不需要任何第三方库就可以直接在Windows下运行,从这一点来看,MinGW更像是VC的跨平台替代品。MinGW可以从MinGW的官方网站 http://www.mingw.org/ 上获得。
    安装MinGW的过程很简单,有两种方案。

    1、直接从 http://sf.net/project/showfiles.php?group_id=2435 下载各种工具包,然后解压到同一个目录(即你设定的MinGW安装目录)中即可。这种方法的下载速度比较快,也能自由选择工具版本,但是你得对MinGW比较熟悉才行,否则你可能不知道需要下载哪些工具包,以及各种工具包的版本搭配关系。把MinGW各种工具包的最新版本凑合在一起,似乎并不能正常工作,反正我把各种工具包的最新版本混合在一起后,没有成功地构建出TBB库。

    2、下载MinGW-5.1.3.exe(http://downloads.sourceforge.net/mingw/MinGW-5.1.3.exe?modtime=1168811236&big_mirror=1),然后用这个自动安装程序从网络安装MinGW。这种方法操作简单,只要点击需要下载的工具包前面的选择框,然后等待程序运行数个小时候即可安装完毕。

    实际上为了节省时间,我是这样安装的,先用迅雷下载MinGW-5.1.3.exe,随后运行MinGW-5.1.3.exe,当它开始下载工具包时,点击CANCEL退出程序,然后在MinGW-5.1.3.exe的当前目录下找到mingw.ini这个文本文件,查看[current]项下的工具包文件名列表,从中选择需要的工具包名称,然后从 http://sf.net/project/showfiles.php?group_id=2435 网页找到这些工具包URL,再用迅雷下载。用迅雷的好处是,可以从国内IP获得这些工具包文件,十分钟内就可以下载完毕并安装好一个可使用的MinGW环境。

    构建TBB库需要的MinGW工具包有:

    mingw-runtime-3.14.tar.gz
    w32api-3.11.tar.gz
    binutils-2.17.50-20060824-1.tar.gz
    gcc-core-3.4.5-20060117-1.tar.gz
    gcc-g++-3.4.5-20060117-1.tar.gz
    mingw32-make-3.81-2.tar.gz

    安装好MinGW(就是把各种工具包解压到一个目录中那么简单)后,别忘了给Windows环境变量中的PATH变量中添加上你的MinGW安装目录。

    按照上述步骤搭建好MinGW环境后,从开始菜单中运行 Intel C++ Build Environment for applications running on IA-32,进入Intel C++ Compiler命令行编译环境,再进入TBB源代码解压目录(也就是有Makefile文件的那个目录),然后运行mingw32-make.exe即可成功编译出最新版本的TBB库。

2008年12月7日

ACE_DEBUG中的匹配符说明

由 晨笛 — 分类目录: C/C++评论暂缺

/**
* Format a message to the thread-safe ACE logging mechanism.  Valid
* options (prefixed by ‘%’, as in printf format strings) include:
*  – ‘A’: print an ACE_timer_t value (which could be either double
*         or ACE_UINT32.)
*  – ‘a’: abort the program at this point abruptly.
*  – ‘c’: print a character
*  – ‘C’: print a character string
*  – ‘i’, ‘d’: print a decimal number
*  – ‘I’: indent according to nesting depth (obtained from
*         ACE_Trace::get_nesting_indent()).
*  – ‘e’, ‘E’, ‘f’, ‘F’, ‘g’, ‘G’: print a double
*  – ‘l’: print line number where an error occurred.
*  – ‘M’: print the name of the priority of the message.
*  – ‘m’: return the message corresponding to errno value, e.g., as
*         done by strerror()
*  – ‘N’: print file name where the error occurred.
*  – ‘n’: print the name of the program (or “<unknown>” if not set)
*  – ‘o’: print as an octal number
*  – ‘P’: print out the current process id
*  – ‘p’: print out the appropriate errno message from sys_errlist,
*         e.g., as done by perror()
*  – ‘Q’: print out the uint64 number
*  – ‘q’: print out the int64 number
*  – ‘@’: print a void* pointer (in hexadecimal)
*  – ‘r’: call the function pointed to by the corresponding argument
*  – ‘R’: print return status
*  – ‘S’: print out the appropriate _sys_siglist entry corresponding
*         to var-argument.
*  – ’s’: print out a character string
*  – ‘T’: print timestamp in hour:minute:sec:usec format.
*  – ‘D’: print timestamp in month/day/year hour:minute:sec:usec format.
*  – ‘t’: print thread id (1 if single-threaded)
*  – ‘u’: print as unsigned int
*  – ‘w’: prints a wide character
*  – ‘W’: print a wide character string
*  – ‘x’: print as a hex number
*  – ‘X’: print as a hex number
*  – ‘z’: print an ACE_OS::WChar character
*  – ‘Z’: print an ACE_OS::WChar character string
*  – ‘%’: print out a single percent sign, ‘%’
*/

2008年08月25日

发现VS的一个使用技巧

由 晨笛 — 分类目录: C/C++评论暂缺

昨天安装了一下QT的开发包,在安装目录下发现一个环境配置bat文件,打开看了一下,发现一个vs的使用技巧。原来vs的执行程序devenv可以接受命令行参数,通过devenv /?得到了他的帮助信息。

Microsoft (R) Visual Studio 8.0.50727.762 版。
版权所有 (C) Microsoft Corp 1984-2005。保留所有权利。

用法:
devenv  [solutionfile | projectfile | anyfile.ext]  [switches]

devenv 的第一个参数通常是一个解决方案文件或项目文件。如果您希望在编辑器中自动打开文件,也可以使用任何其他文件作为第一个参数。当您输入项目文件时,IDE 会在项目文件的父目录中查找与该项目文件具有相同基名称的 .sln 文件。如果不存在这样的 .sln 文件,IDE 将查找引用该项目的单个 .sln 文件。如果不存在这样的单个.sln 文件,则 IDE 将创建一个具有默认 .sln 文件名且未保存的解决方案,其基名称与项目文件的基名称相同。

命令行编译:
devenv solutionfile.sln /build solutionconfig [ /project projectnameorfile [ /projectconfig name ] ]
可用的命令行开关:

/Build          使用指定的解决方案配置生成解决方案或项目。例如“Debug”。如果可能存在多个平台,则配置名称必须用引号括起来并且包含平台名称。例如“Debug|Win32”。
/Clean          删除生成结果。
/Command        启动 IDE 并执行该命令。
/Deploy         生成并部署指定的生成配置。
/Edit           在此应用程序的运行实例中打开指定文件。如果没有正在运行的实例,则启动一个具有简化窗口布局的新实例。
/LCID           设置 IDE 中用于用户界面的默认语言。
/Log            将 IDE 活动记录到指定的文件以用于故障排除。
/NoVSIP         禁用用于 VSIP 测试的 VSIP 开发人员许可证密钥。
/Out            将生成日志追加到指定的文件中。
/Project        指定生成、清理或部署的项目。必须和 /Build、/Rebuild、/Clean 或 /Deploy 一起使用。
/ProjectConfig  重写解决方案配置中指定的项目配置。例如“Debug”。如果可能存在多个平台,则配置名称必须用引号括起来并包含平台名称。例如“Debug|Win32”。必须和/Project 一起使用。
/Rebuild        先清理,然后使用指定配置生成解决方案或项目。
/ResetAddin     移除与特定外接程序关联的命令和命令用户界面。
/ResetSettings  恢复 IDE 的默认设置,还可以重置为指定的 VSSettings 文件。
/ResetSkipPkgs  清除所有添加到 VSPackages 的 SkipLoading 标记。
/Run            编译并运行指定的解决方案。
/RunExit        编译并运行指定的解决方案然后关闭 IDE。
/SafeMode       以安全模式启动 IDE,加载最少数量的窗口。
/Upgrade        升级项目或解决方案以及其中的所有项目。并相应地创建这些文件的备份。有关备份过程的更多信息,请参见“Visual Studio 转换向导”上的帮助。

产品特定的开关:

/debugexe       打开要调试的指定可执行文件。命令行的其余部分作为它的参数传递到此执行文件。
/useenv         使用 PATH、INCLUDE、LIBPATH 和 LIB 环境变量而不是使用 VC++ 生成的 IDE 路径。

要从命令行附加调试器,请使用:
VsJITDebugger.exe -p <pid>

2008年04月27日

怎样给多维数组动态分配内存

由 晨笛 — 分类目录: C/C++评论暂缺
1
2
3
4
5
6
7
8
9
10
11
12
//Allocate:
int **p = new int* [m];
for(int i = 0 ; i < m ; i++)
    p[i] = new int[n];
//Use:
for(int i = 0 ; i < m; i++)
    for(int j = 0 ; j < n ; j++)
        p[i][j] = i * j;
//Free:
for(int i = 0 ; i < m ; i++)
    delete[] p[i];
delete[] p;

1. 演示形为int[2][3]的二维动态数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int n1, n2;
const int DIM1 = 2;
const int DIM2 = 3;
// 构造数组
int **ppi = new int*[DIM1];
for(n1 = 0; n1 < DIM1; n1++)
{
    ppi[n1] = new int[DIM2];
}
// 填充数据
for(n1 = 0; n1 < DIM1; n1++)
{
    for(n2 = 0; n2 < DIM2; n2++)
    {
        ppi[n1][n2] = n1 * 10 + n2;
    }
}
// 输出
for(n1 = 0; n1 < DIM1; n1++)
{
    for(n2 = 0; n2 < DIM2; n2++)
    {
        afxDump << "ppi[" << n1 << "][" << n2 << "] = " 
            << ppi[n1][n2] << "n";
    }
}
// 释放数组
for(n1 = 0; n1 < DIM1; n1++)
{
    delete [] ppi[n1];
}
delete [] ppi;

2. 三维动态数组(int[2][3][4])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
int n1, n2, n3;
const int DIM1 = 2;
const int DIM2 = 3;
const int DIM3 = 4;
// 构造数组
int ***ppi = new int**[DIM1];
for(n1 = 0; n1 < DIM1; n1++)
{
    ppi[n1] = new int*[DIM2];
    for(n2 = 0; n2 < DIM2; n2++)
    {
        ppi[n1][n2] = new int[DIM3];
    }
}
// 填充数据
for(n1 = 0; n1 < DIM1; n1++)
{
    for(n2 = 0; n2 < DIM2; n2++)
    {
        for(n3 = 0; n3 < DIM3; n3++)
        {
            ppi[n1][n2][n3] = n1 * 100 + n2 * 10 + n3;
        }
    }
}
// 输出
for(n1 = 0; n1 < DIM1; n1++)
{
    for(n2 = 0; n2 < DIM2; n2++)
    {
        for(n3 = 0; n3 < DIM3; n3++)
        {
            afxDump << "ppi[" << n1 << "][" << n2 << "][" << n3 << "] = "
                    << ppi[n1][n2][n3] << "n";
        }
    }
}
// 释放数组
for(n1 = 0; n1 < DIM1; n1++)
{
    for(n2 = 0; n2 < DIM2; n2++)
    {
        delete [] ppi[n1][n2];
    }
    delete [] ppi[n1];
}
delete [] ppi;

多维数组下标操作符重载一法

由 晨笛 — 分类目录: C/C++评论暂缺

刚学习C++操作符重载时,我就想过如何重载多维下标操作符“[][]”的问题,这里仅就二维的特殊情况提出一种方法,希望可以起到抛砖引玉的作用。

我们假设有一个Matrix类用来封装矩阵,并希望用[][]来取得矩阵对应位置的元素值。分析一下m.[a][b],可以看做是m.operator [a].operator [b]。所以要让第一个[]返回一个也重载了[]的辅助类,再把a传到那个辅助类中,想办法在后一个类的[]中实现对应元素的返回。代码如下(忽略了其他成员函数和越界检查):
[cpp]
class assis//辅助类
{
public:
int operator [](int index)
{
index2=index-1;
return pdata[index1*ncol+index2];
};
int * pData;
int index1,index2;
int ncol,nrow;
};
class Matrix//矩阵类
{
public:
//其他成员函数
assis operator [](int index)
{
assis ret;
ret.pData=pData;
ret.ncol=ncol;
ret.nrow=nrow;
ret.index1=index-1;
return ret;
};
private:
int * pData;
int nrow,ncol;
//其他成员变量
};
[/cpp]

页数: 1 2 下一页
© 2010 晨笛的博客 All rights reserved - Wallow theme by TwoBeers Crew - Powered by WordPress - 使用愉快!