??xml version="1.0" encoding="utf-8" standalone="yes"?>日韩精品久久久久久,亚洲va久久久噜噜噜久久,亚洲精品乱码久久久久久蜜桃http://www.shnenglu.com/xpzhou/要是生命真的有如果,׃会有q么多的遗憾Q要是等一分钟可以如愿Q就不会有这么多的伤?..zh-cnWed, 07 May 2025 18:56:23 GMTWed, 07 May 2025 18:56:23 GMT60HOWTO: Create Debug Symbols for a Visual C++ Applicationhttp://www.shnenglu.com/xpzhou/archive/2007/06/11/26109.html榕树?/dc:creator>榕树?/author>Mon, 11 Jun 2007 14:54:00 GMThttp://www.shnenglu.com/xpzhou/archive/2007/06/11/26109.htmlhttp://www.shnenglu.com/xpzhou/comments/26109.htmlhttp://www.shnenglu.com/xpzhou/archive/2007/06/11/26109.html#Feedback0http://www.shnenglu.com/xpzhou/comments/commentRss/26109.htmlhttp://www.shnenglu.com/xpzhou/services/trackbacks/26109.html 1. ?#8220;解决Ҏ资源理?#8221;中,叛_要修改的目Q然后单?strong>属?/strong>?/td> 2. ?#8220;配置属?#8221;H口中,单击C/C++ 文g夹,然后单击常规?/td> 3. ?strong>调试信息格式下拉列表中,单击选择E序数据?(/Zi)?/td> 4. 如果您希望在调试转储文g或执行实时调试时获得有关局部变量的信息Q请单击选择优化下拉列表中的用 (/Od)?/td> 5. ?#8220;配置属?#8221;H口?Linker 文g夹中Q确?#8220;调试”子类别的生成调试信息属性设|ؓ?(/DEBUG)?strong>备注Q尽ƈ不要求您在同一子类别中同样启用生成映射文gQ但该选项会创Z?.map 文gQ当您只有发生访问冲H的地址Ӟ该文件对定发生故障的位|可能很有用。有x多信息,请参?#8220;参?#8221;部分? ?Visual C++ 6.0 开发环境中为应用程序创建符hӞ
1. ?strong>目菜单上,选择?/td>
2. ?strong>C/C++ 选项卡上Q将cd更改?strong>常规?/td>
3. ?strong>调试信息下拉列表中,选择E序数据?/strong>?strong>备注Q如果您希望在调试{储文件或执行实时调试时获得有兛_部变量的信息Q还应该选择优化下拉列表中的用Q调试)?br>
4. ?strong>链接选项卡上Q将cd更改?strong>调试?/td>
5. ?strong>调试信息部分Q确保选中调试信息 选项Q然后选择两种格式?strong>备注Q尽不要求您在链接选项卡上同样启用常规cd中的生成映射文gQ但该选项会创Z?.map 文gQ当您只有发生访问冲H的地址Ӟ该文件对定发生故障的位|可能很有用。(有关更多信息Q请参见“参?#8221;。)


]]>
VC++6.0~译环境介绍http://www.shnenglu.com/xpzhou/archive/2007/06/08/25807.html榕树?/dc:creator>榕树?/author>Fri, 08 Jun 2007 02:00:00 GMThttp://www.shnenglu.com/xpzhou/archive/2007/06/08/25807.htmlhttp://www.shnenglu.com/xpzhou/comments/25807.htmlhttp://www.shnenglu.com/xpzhou/archive/2007/06/08/25807.html#Feedback0http://www.shnenglu.com/xpzhou/comments/commentRss/25807.htmlhttp://www.shnenglu.com/xpzhou/services/trackbacks/25807.html

大家可能一直在?/font>VC开发YӞ但是对于q个~译器却未必很了解。原因是多方面的。大多数情况下,我们只停留在“使用”它,而不会想?#8220;了解”它。因为它只是一个工P我们宁可把更多的_֊攑֜C++语言和Y件设计上。我们习惯于q样一U?#8220;模式”Q徏立一个项目,然后写代码,然后~译Q反反复复调试。但是,所谓:“公欲善其事,必先利其?#8221;。如果我们精?/span>VC开发环境,我们是不是能够做得更加游刃有余呢Q?/span>


Visual C++可新建的 Projects目

Visual C++可新建的 File文g

 

Visual C++的Build讄
1.Compile TEST.cpp选项 只编译当前文件而不调用链接器或其它工具。输出窗口将昄~译q程查出的错误或警告信息Q在错误信息处单击鼠标右键,可以得到错误代码的位|?br>2. Build TEST.exe 选项 Ҏ后修改过的源文gq行~译和链?br>3. Rebuild All选项 该选项允许用户~译所有的源文Ӟ而不它们何时曾l被修改q?br>4. Batch Build选项 该选项能单步重新徏立多个工E文Ӟq允许用h定要建立的项目类?VC提供了两U目标应用程序类?Win32 ReleaseQ发行版Q、Win32 DebugQ调试版Q?/font>


 

我们先来看一?/font>VC的处理流E,大致分ؓ两步Q编译和q接。源文g通过~译生成?/span>.obj文gQ所?/span>.obj文g?/span>.lib文g通过q接生成.exe文g?/span>.dll文g。下面,我们分别讨论q两个步骤的一些细节?/font>

 

工程配置对话?/strong> 在这个对话框中,左上方的下拉列表框用于选择一U工E配|,包括有Win32 Debug、Win32 Release和All ConfigurationsQ指前两U配|一PQ某些选项在不同的工程配置中有不同的缺省倹{左边的树Ş视图l出了当前工E所有的文g及分cLc如果我们把工程“Schedule”|ؓ高亮昄Q正如图9-1那样Q,对话框的双׃出现d十个选项卡,其中列出了与工程有关的各U选项Q不选项卡中有一个Reset按钮Q按下它后可以把选项卡内的各设|恢复到生成工程时的初始倹{如果我们在树Ş视图中选择一个文件类或一个文Ӟ那么对话框右边的选项卡会自动减少C个或两个Q其中列出的都是与选中的文件类或文件有关的选项?/font>

 ~译参数的设|?/span>。主要通过VC的菜单项Project->Settings->C/C++|完成。我们可以看到这一늚最下面Project Options中的内容Q一般如下:

/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"Debug/WritingDlgTest.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c

各个参数代表的意义,可以参?/font>Project Option语法解释。比?/span>/nologo表示~译时不在输出窗口显C些设|(我们可以把这个参数去掉来看看效果Q等{。一般我们不会直接修改这些设|,而是通过q一|上面?/span>Category中的各项来完成?/font>

1)GeneralQ一些M讄?/span>Warning level用来控制警告信息Q?/span>None表示不显CZQ何警告,L1表示只显CZ重的警告QL2表示昄比L1ơ严重的警告QL4则表C显C出所有的警告Q包括那些安全忽略的警告Q?/span>Warnings as errors警告信息当作错误处?/span>Q这样在~译完毕后就无法启动q接器来q行q接Q?/span>Optimizations是代码优化,可以?/span>Category?/span>Optimizations中q行更细的设|;Generate browse info用以生成.sbr文gQ记录类、变量等W号信息Q可以在Category?/span>Listing Files中q行更多的设|?/span>Debug infoQ生成调试信息:NoneQ不产生M调试信息Q编译比较快Q;Line Numbers OnlyQ仅生成全局的和外部W号的调试信息到.OBJ文g?/span>.EXE文gQ减目标文件的寸Q?/span>C 7.0- CompatibleQ记录调试器用到的所有符号信息到.OBJ文g?/span>.EXE文gQ?/span>Program DatabaseQ创?/span>.PDB文g记录所有调试信息;Program Database for "Edit & Continue"Q创?/span>.PDB文g记录所有调试信息,q且支持调试时编辑?/font>

 

2)C++ LanguageQ?/span>pointer_to_member representation用来讄cd?/span>/引用的先后关p,一般ؓBest-Case Always表示在引用类之前该类肯定已经定义了;Enable Exception HandlingQ进行同步的异常处理Q?/span>Enable Run-Time Type Informationqɾ~译器增加代码在q行时进行对象类型检查;Disable Construction DisplacementsQ设|类构?/span>/析构函数调用虚函数问题?/font>

 

  

3)Code GenerationQ?/span>Processor表示代码指o优化Q可以ؓ80386?/span>80486?/span>Pentium?/span>Pentium ProQ或?/span>Blend表示混合以上各种优化?/span>Use run-time library用以指定E序q行时用的q行时库Q单U程或多U程Q?/span>Debug版本?/span>Release版本Q,有一个原则就是,一个进E不要同时用几个版本的q行时库?/span>Single-ThreadedQ静态连?/span>LIBC.LIB库;Debug Single-ThreadedQ静态连?/span>LIBCD.LIB库;MultithreadedQ静态连?/span>LIBCMT.LIB库;Debug MultithreadedQ静态连?/span>LIBCMTD.LIB库;Multithreaded DLLQ动态连?/span>MSVCRT.DLL库;Debug Multithreaded DLLQ动态连?/span>MSVCRTD.DLL库。连接了单线E库׃支持多线E调用,q接了多U程库就要求创徏多线E的应用E序?/span>Calling convention可以用来讑֮调用U定Q有三种Q?/span>__cdecl?/span>__fastcall?/span>__stdcall。各U调用约定的主要区别在于Q函数调用时Q函数的参数是从左到叛_入堆栈还是从叛_左压入堆栈;在函数返回时Q由函数的调用者来清理压入堆栈的参数还是由函数本n来清理;以及在编译时对函数名q行的命名修饎ͼ可以通过Listing Files看到各种命名修饰方式Q?/span>Struct member alignment用以指定数据l构中的成员变量在内存中是按几字节对齐的Q根据计机数据ȝ的位敎ͼ不同的对齐方式存取数据的速度不一栗这个参数对数据包网l传输等应用ؓ重要Q不是存取速度问题Q而是数据位的_定义问题Q一般在E序中?/span>#pragma pack来指定?/font>

 

4)CustomizeQ?/span>Disable Language ExtensionsQ表CZ使用微Y为标?/span>C做的语言扩展Q?/span>Eliminate Duplicate StringsQ主要用于字W串优化Q将字符串放到缓充池里以节省I间Q,使用q个参数Q?/font>

char *sBuffer = "This is a character buffer";

char *tBuffer = "This is a character buffer";

sBuffer?/span>tBuffer指向的是同一块内存空_Enable Function-Level Linking Q告诉编译器各个函数按打包格式~译Q?/span>Enables minimal rebuildQ通过保存兌信息?/span>.IDB文gQɾ~译器只Ҏ新类定义改动q的源文件进行重~译Q提高编译速度Q?/span>Enable Incremental CompilationQ同样通过.IDB文g保存的信息,只重~译最新改动过的函敎ͼSuppress Startup Banner and Information MessagesQ用以控制参数是否在outputH口输出?/font>

 

5) Listing FilesQ?/span>Generate browse info的功能上面已l提到过。这里可以进行更多的讄?/span>Exclude Local Variables from Browse Info表示是否局部变量的信息攑ֈ.SBR文g中?/span>Listing file type可以讄生成的列表信息文件的内容Q?/span>Assembly-Only Listing仅生成汇~代码文Ӟ.ASM扩展名)Q?/span>Assembly With Machine Code生成机器代码和汇~代码文Ӟ.COD扩展名)Q?/span>Assembly With Source Code生成源代码和汇编代码文gQ?/span>.ASM扩展名)Q?/span>Assembly, Machine Code, and Source生成机器码、源代码和汇~代码文Ӟ.COD扩展名)?/span>Listing file name为生成的信息文g的\径,一般ؓDebug?/span>Release目录下,生成的文件名自动取源文g的文件名?/font>

 

 

6)OptimizationsQ?/span>代码优化讄。可以选择Maximize Speed生成最快速的代码Q或Minimize Size生成最尺寸的E序Q或?/span>Customize定制优化。定制的内容包括Q?/font>

Assume No AliasingQ不使用别名Q提高速度Q;

Assume Aliasing Across Function CallsQ仅函数内部不用别名;

Global OptimizationsQ全局优化Q比如经常用到的变量使用寄存器保存,或者@环内的计优化,?/font>

i = -100;

while( i < 0 ){    i += x + y;}

会被优化?/font>

i = -100;

t = x + y;

while( i < 0 ){i += t;}

Generate Intrinsic FunctionsQ用内部函数替换一些函数调用(提高速度Q;

Improve Float ConsistencyQQ点运方面的优化Q?/font>

Favor Small CodeQ程序(exe?/span>dllQ尺怼化优先于代码速度优化Q?/font>

Favor Fast CodeQ程序(exe?/span>dllQ代码速度优化优先于尺怼化;

Frame-Pointer OmissionQ不使用帧指针,以提高函数调用速度Q?/font>

Full OptimizationQ组合了几种参数Q以生成最快的E序代码?/font>

Inline function expansionQ内联函数扩展的三种优化Q用内联可以节省函数调用的开销Q加快程序速度Q:Disable不用内联;Only __inlineQ仅函数定义前有inline?/span>__inline标记使用内联Q?/span>Any SuitableQ除?/span>inline?/span>__inline标记的函数外Q编译器“觉得”应该使用内联的函敎ͼ都用内联?/font>

 

7)Precompiled HeadersQ预~译头文件的讄?/font>

 预编译头的概念: 所谓的预编译头是把一个工E中的那一部分代码,预先~译好放在一个文仉(通常是以.pch为扩展名?Q这个文件就UCؓ预编译头文gq些预先~译好的代码可以是Q何的C/C++代码--------甚至是inline的函敎ͼ但是必须是稳定的Q在工程开发的q程中不会被l常改变。如果这些代码被修改Q则需要重新编译生成预~译头文件?/font>你可将一些公q、不大变动的头文Ӟ比如FILEX.h{)集中攑ֈstdafx.h中,q一部分代码׃必每ơ都重新~译Q除非是Rebuild AllQ?/font>注意生成预编译头文g是很耗时间的。同时你得注意预~译头文仉常很大Q通常?-7M大?span lang=ZH-CN>使用预编译可以提高重复编译的速度?/span>

  也许你会问:现在的编译器都有Time stamp的功能,~译器在~译整个工程的时候,它只会编译那些经q修改的文gQ而不会去~译那些从上ơ编译过Q到现在没有被修改过的文件。那么ؓ什么还要预~译头文件呢Q答案在q里Q我们知道编译器是以文g为单位编译的Q一个文件经q修改后Q会重新~译整个文gQ当然在q个文g里包含的所有头文g中的东西Q?eg Macro, Preprocessor Q都要重新处理一遍。VC的预~译头文件保存的正是q部分信息。以避免每次都要重新处理q些头文件?/font>

1.q里是用工E里的设|,/Yu”stdafx.h”。如果用了/YuQ就是说使用了预~译Q我们在每个.cpp文g的最开_我强调一遍是最开_包含 你指定生pch文g?h文gQ默认是stdafx.hQ不然就会有问题。如果你没有包含q个文gQ就告诉你Unexpected file end. 如果你不是在最开头包含的

2.如果你把pch文g不小心丢了,最单的办法是选中W一个选项“Not using....",q样根本不用预~译头也不去Lpch文gQ就不会出错了,但是q样做的后果是每ơ编译、连接都化更多的旉。也可以选第二个选项”Automatic use of",然后?#8220;Through header”力填上stdafx.hQ这样如果没有pch文gpȝ会自动生成一个pchQ如果有的话׃用这个pchQ这个选项是比?#8220;”的。第三个选项是强行创Z个pch文gQ第四个选项是直接用pch文g。当?#8220;Through headers”里都填stdafx.h了?/font>

让编译器生成一个pch文g可以了。也是说把 stdafx.cppQ即指定/Yc的那个cpp文gQ从新编译一遍就可以了。当然你可以d?Rebuild all?/font>

 

8) PreprocessorQ预~译处理?/span>我们可以在这里预先定义一些宏名,指定部分或所有符号具有未定义状?span lang=ZH-CN>?/span>Additional include directoriesQ可以指定额外的包含目录Q一般是相对于本目的目录,?/span>..\Include?/font>

 

Linkq接参数的设|?/strong>。主要通过VC的菜单项Project->Settings->Link|完成。我们可以看到这一늚最下面Project Options中的内容Q一般如下:

/nologo /subsystem:windows /incremental:yes /pdb:"Debug/WritingDlgTest.pdb" /debug /machine:I386 /out:"Debug/WritingDlgTest.exe" /pdbtype:sept

下面我们分别来看一?/font>Category中的各项讄?/font>

 

1GeneralQ一些M讄。可以设|生成的文g路径、文件名 ?/span>?#8220;Output   file   name:”下面的编辑框中可输入Q?#8220;C:\bin\TEST.exe”Q连接的库文ӞGenerate debug infoQ生?/span>Debug信息?/span>.PDB文gQ具体格式可以在Category->Debug中设|)Q?/span>Ignore All Default LibrariesQ放弃所有默认的库连接;Link IncrementallyQ通过生成. ILK文g实现递增式连接以提高后箋q接速度Q但一般这U方式下生成的文ӞEXE?/span>DLLQ较大;Generate MapfileQ生?/span>.MAP文g记录模块相关信息Q?/span>Enable ProfilingQ这个参数通常?/span>Generate Mapfile参数同时使用Q而且如果产生Debug信息的话Q不能用.PDB文gQ而且必须?/span>Microsoft Format?/span>  

2CustomizeQ这里可以进行用程序数据库文g的设|?/span>选中Use program database允许使用E序数据库,q样q接器会把调试信息放在程序数据库中,如果不选中该选项Q那么也不能使用递增q接方式。Force File Output Q?/span>即某个模块引用了一些未定义或者重复定义的W号Q连接器仍然?span lang=ZH-CN>强制Q但不一定能正确q行Q?span lang=ZH-CN>产生输出文gQ?/span>EXE?/span>DLLQ;Print Progress MessagesQ可以将q接q程中的q度信息输出?/span>OutputH口?/font>

  

3. DebugQ?/span>讄是否生成调试信息Q以及调试信息的格式。格式可以有Microsoft Format?/span>COFF FormatQ?/span>Common Object File FormatQ和Both FormatsQ两U都?span lang=ZH-CN>Q三U选择Q?/span>Separate TypesQ表C将Debug格式信息以独立的.PDB文g存放Q还是直接放在各个源文g?/span>.PDB文g中。选中的话Q表C采用后者的方式Q这U方式调试启动比较快?/font>

4InputQ?/span>q里可以指定要连接的库文Ӟ攑ּq接的库文g。还可以增加额外的库文g目录Q一般是相对于本目的目录,?/span>..\Lib?/span>Force Symbol ReferencesQ可以指定连接特定符号定义的库?/span> ??#8220;Object/library   Modules:”下面的编辑框中输入:“TestDll.lib”Q在“Additional   library   path:”下面的编辑框中输入:“C:\bin”。可用Workspace另一个工E编译的静态库
 

5.OutputQ?/span>Base Address可以改变E序默认的基地址Q?/span>EXE文g默认?/span>0x400000Q?/span>DLL默认?/span>0x10000000Q,操作pȝ装蝲一个程序时L试着先从q个基地址开始?/span>Entry-Point Symbol可以指定E序的入口地址Q一般ؓ一个函数名Q且必须采用__stdcall调用U定Q。一?/span>Win32的程序,EXE的入口ؓWinMainQ?/span>DLL的入口ؓDllEntryPointQ最好让q接器自动设|程序的入口炏V默认情况下Q通过一?/span>C的运行时库函数来实现Q控制台E序采用mainCRTStartup (?/span>wmainCRTStartup)去调用程序的main (?/span>wmain)函数Q?/span>WindowsE序采用WinMainCRTStartup (?/span> wWinMainCRTStartup)调用E序?/span>WinMain (?/span> wWinMainQ必采?/span>__stdcall调用U定)Q?/span>DLL采用_DllMainCRTStartup调用DllMain函数Q必采?/span>__stdcall调用U定Q?/span>Stack allocationsQ用以设|程序用的堆栈大小Q请使用十进ӞQ默认ؓ1兆字节?/span>Version Information告诉q接器在EXE?/span>DLL文g的开始部分放上版本号?/span>一般情况下都不用改变?/font>

 

值得注意的是Q上面各个参数是大小写敏感的Q在参数后加?#8220;-”表示该参数无效;各个参数值选项?#8220;*”的表CZؓ该参数的默认|可以使用右上角?#8220;Reset”按钮来恢复该늚所有默认设|?/font>

 

9)Resources选项?/strong>  Resources选项卡控制着VC6的资源编译器。如?-5所C,我们可以指定~译后生成的资源文g的\径,资源的语acdQ以及额外的资源包含目录?/font>

 MIDL选项?q个选项卡与COMQ组件对象模型)~程有关Q我们不讨论它?/font>

 

10)Browse Info选项?在这个选项卡中Q我们可以指定是否在建立工程的同时也生成览信息文gQ有了这个文件后Q我们就能够在文本编辑器中通过兌菜单的相应命令快速定位到某个W号的定义或引用的地斏V?/font>

 

11)Pre-link step

q个选项卡用于添加在q接之前要执行的命o?/font>

 

l2) Post-build step

q个选项卡用于添加在工程建立完毕之后要执行的命o ?“copy debug\TestDll.lib C:\bin\TestDll.lib” q在C盘下Z个bin目录 做的件事情就是把TestDLL.lib拯到C:\bin所在的文g夹中
 

 

其它一些参数设|?/font>?/font>

  

13) Project->Settings->GeneralQ可以设|连?/span>MFC库的方式Q静态或动态)。如果是动态连接,在你的Y件发布时不要忘了带上MFC?/span>DLL?/span>W二个选项用于指定在编译连接过E中生成的中间文件和输出文g的存攄录,对于调试版本来说Q缺省的目录是工E下面的“Debug”子目录。最下面的第三个选项用于指定是否允许每种工程配置都有自己的文件依赖关p(主要指头文gQ,׃l大多数工程的调试版本和发布版本都具有相同的文g依赖关系Q所以通常不需要更改该选项?/font>

 

14) Project->Settings->DebugQ可以设|调试时q行的可执行文gQ?/span>如果正在~写的程序是一个DLLQ那么应在此处指定一个用来调试该DLL的EXE文g。另外三个选项可以指定用于调试的工作目录,开始调试时l程序传送的命o行参敎ͼ以及q行q程调试时可执行文g的\径。把cd切换到Additional DLLs后,我们可以指定在开始调试时是否Z些额外的DLL装蝲调试W号信息Q只有装载了W号信息后才能跟t进DLL?/font>

 

15)Project->Settings->Custom BuildQ可以设|编?/span>/q接成功后自动执行一些操作。比较有用的是,?/span>COM时希?/span>VC对编译通过?/span>COM文g自动注册Q可以如下设|:

Description: Register COM

Commands: regsvr32 /s /c $(TargetPath)

echo regsvr32 exe.time > $(TargetDir)\$(TargetName).trg

Outputs: $(TargetDir)\$(TargetName).trg

 

16)Tools->Options->DirectoriesQ设|系l的Include?/span>Library路径?/font>

 

一些小H门

1) 有时候,你可能在~译的时候,计算机突焉法关ZQ可能某Z心C甉|或你的内存不E_{原因)。当你重启机器后打开刚才的项目,重新q行~译Q发?/span>VC会崩掉。你或许以ؓ你的VC~译器坏了,其实不然Q你试试~译其它目Q还是好的!Q,你只要将目?/span>.ncb?/span>.opt?/span>.aps?/span>.clw文g以及Debug?/span>Release目录下的所有文仉删掉Q然后重新编译就行了?/span> 

2) 如果你想与别人共享你的源代码目Q但是把整个目做拷贝又太大。你完全可以删掉以下文gQ?/span>.dsw?/span>.ncb?/span>.opt?/span>.aps?/span>.clw?/span>. plg文g以及Debug?/span>Release目录下的所有文件?/font>

3) 当你?/span>Workspace中包含多?/span>Project的时候,你可能不能直观地、一眼看出来哪个是当前项目。可以如下设|:Tools->Options->FormatQ然后在Category中选择Workspace windowQ改变其默认的字体(比如设成FixedsysQ就行了?/font>

4) 如何l已有的Project改名字?该Projectx。然后以文本格式打开.dsp文gQ替换原来的Project名字卛_?/font>

5) VC6对类成员的智能提C功能很有用Q但有时候会q。你可以先关掉项目,?/span>.clw?/span>.ncb删掉Q然后重新打开目Q点击菜单项View->ClassWizardQ在弹出的对话框中按一?#8220;Add All”按钮Q重?/span>Rebuild All。应该可以解决问题?/font>

 

?

VC文g扩展名解d?/font>

.APSQ存放二q制资源的中间文ӞVC把当前资源文件{换成二进制格式,q存攑֜APS文g中,以加快资源装载速度。资源辅助文件?/font>

.BMPQ位图资源文件?/font>

.BSCQ浏览信息文Ӟ由浏览信息维护工PBSCMAKEQ从原始览信息文gQ?SBRQ中生成QBSC文g可以用来在源代码~辑H口中进行快速定位。用于浏览项目信息的Q如果用source brower的话必Lq个文g。可以在project options里去掉Generate Browse Info FileQ这样可以加快编译进度?/font>

.CQ用C语言~写的源代码文g?/font>

.CLWQClassWizard生成的用来存攄信息的文件。classwizard信息文gQini文g的格式?/font>

.CNTQ用来定义帮助文件中“Contents”的结构?/font>

.CPP?CXXQ用C++语言~写的源代码文g?/font>

.CURQ光标资源文件?/font>

.DEFQ模块定义文Ӟ供生成动态链接库时用?/font>

.DLGQ定义对话框资源的独立文件。这U文件对于VC工程来说q必需Q因为VC一般把对话框资源放?RC资源定义文g中?/font>

.DSPQVC开发环境生成的工程文gQVC4及以前版本用MAK文g来定义工E。项目文Ӟ文本格式?/font>

.DSWQVC开发环境生成的WorkSpace文gQ用来把多个工程l织C个WorkSpace中。工作区文gQ与.dsp差不多?/font>

.EXPQ由LIB工具从DEF文g生成的输出文Ӟ其中包含了函数和数据目的输Z息,LINK工具用EXP文g来创建动态链接库。只有在~译DLL时才会生成,记录了DLL文g中的一些信息?/font>

.H?HPP?HXXQ用C/C++语言~写的头文gQ通常用来定义数据cdQ声明变量、函数、结构和cR?/font>

.HLPQWindows帮助文g?/font>

.HMQ在Help工程中,该文件定义了帮助文g与对话框、菜单或其它资源之间ID值的对应关系?/font>

.HPJQ由Help Workshop生成的Help工程文gQ用来控制Help文g的生成过E?/font>

.HPGQ生成帮助的文g的工E?/font>

.ICOQ图标资源文件?/font>

.ILKQ连接过E中生成的一U中间文Ӟ只供LINK工具使用?/font>

.INIQ配|文件?/font>

.LIBQ库文gQLINK工具用它来连接各U输入库Q以便最l生成EXE文g?/font>

.LICQ用戯可证书文Ӟ使用某些ActiveX控g旉要该文g?/font>

.MAKQ即MAKE文gQVC4及以前版本用的工程文gQ用来指定如何徏立一个工E,VC6把MAK文g转换成DSP文g来处理?/font>

.MAPQ由LINK工具生成的一U文本文Ӟ其中包含有被q接的程序的某些信息Q例如程序中的组信息和公q号信息等。执行文件的映像信息记录文g?/font>

.MDPQ旧版本的项目文Ӟ相当?dsp

.NCBQNCB?#8220;No Compile Browser”的羃写,其中存放了供ClassView、WizardBar和Component Gallery使用的信息,由VC开发环境自动生成。无~译览文g。当自动完成功能出问题时可以删除此文件。编译工E后会自动生成?/font>

.OBJQ由~译器或汇编工具生成的目标文Ӟ是模块的二进制中间文件?/font>

.ODLQ用对象描述语言~写的源代码文gQVC用它来生成TLB文g?/font>

.OLBQ带有类型库资源的一U特D的动态链接库Q也叫对象库文g?/font>

.OPTQVC开发环境自动生成的用来存放WorkSpace中各U选项的文件。工E关于开发环境的参数文g。如工具条位|信息等?/font>

.PBI?PBO?PBTQ由VC的性能分析工具PROFILE生成q用的三种文g?/font>

.PCHQ预~译头文Ӟ比较大,q译器在徏立工E时自动生成Q其中存放有工程中已l编译的部分代码Q在以后建立工程时不再重新编译这些代码,以便加快整个~译q程的速度?/font>

.PDBQ程序数据库文gQ在建立工程时自动生成,其中存放E序的各U信息,用来加快调试q程的速度。记录了E序有关的一些数据和调试信息?/font>

.PLGQ编译信息文Ӟ~译时的error和warning信息文g?/font>

.RCQ资源定义文件?/font>

.RC2Q资源定义文Ӟ供一些特D情况下使用?/font>

.REGQ注册表信息文g?/font>

.RESQ二q制资源文gQ资源编译器~译资源定义文g后即生成RES文g?/font>

.RTFQRich Text FormatQ丰富文本格式)文档Q可由Word或写字板来创建,常被用来生成Help文g?/font>

.SBRQVC~译器ؓ每个OBJ文g生成的原始浏览信息文Ӟ览信息l护工具QBSCMAKEQ将利用SBR文g来生成BSC文g?/font>

.TLBQOLE库文Ӟ其中存放了OLE自动化对象的数据cd、模块和接口定义Q自动化服务器通过TLB文gp了解自动化对象的使用Ҏ?/font>

.WAVQ声韌源文件?/font>



]]>
Select模型http://www.shnenglu.com/xpzhou/archive/2007/04/25/22786.html榕树?/dc:creator>榕树?/author>Wed, 25 Apr 2007 01:09:00 GMThttp://www.shnenglu.com/xpzhou/archive/2007/04/25/22786.htmlhttp://www.shnenglu.com/xpzhou/comments/22786.htmlhttp://www.shnenglu.com/xpzhou/archive/2007/04/25/22786.html#Feedback2http://www.shnenglu.com/xpzhou/comments/commentRss/22786.htmlhttp://www.shnenglu.com/xpzhou/services/trackbacks/22786.html套接字模式:d套接字和非阻塞套接字。或者叫同步套接字和异步套接字?br>套接字模型:描述如何对套接字的I/O行ؓq行理?br>Winsock提供的I/O模型一共有五种Q?br>select,WSAAsyncSelect,WSAEventSelect,Overlapped,Completion。今天先讲解select?br>
1Qselect模型Q选择模型Q?br>先看一下下面的q句代码Q?br>int iResult = recv(s, buffer,1024);
q是用来接收数据的,在默认的d模式下的套接字里Qrecv会阻塞在那里Q直到套接字q接上有数据可读Q把数据dbuffer里后recv函数才会q回Q不然就会一直阻塞在那里。在单线E的E序里出现这U情况会DȝE(单线E程序里只有一个默认的ȝE)被阻?q样整个E序被锁dq里Q如果永q没数据发送过来,那么E序׃被永q锁歅R这个问题可以用多线E解冻I但是在有多个套接字连接的情况下,q不是一个好的选择Q扩展性很差。Select模型是Z解决q个问题而出现的?br>再看代码Q?br>
int iResult = ioctlsocket(s, FIOBIO, (unsigned long *)&ul);
iResult = recv(s, buffer,1024);

q一ơrecv的调用不套接字q接上有没有数据可以接收都会马上q回。原因就在于我们用ioctlsocket把套接字讄为非d模式了。不q你跟踪一下就会发玎ͼ在没有数据的情况下,recv实是马上返回了Q但是也q回了一个错误:WSAEWOULDBLOCKQ意思就是请求的操作没有成功完成。看到这里很多h可能会说Q那么就重复调用recvq检查返回|直到成功为止Q但是这样做效率很成问题Q开销太大?br>感谢天才的微软工E师吧,他们l我们提供了好的解决办法?br>先看看select函数
int select(
int nfds,
fd_set FAR *readfds,
fd_set FAR *writefds,
fd_set FAR *exceptfds,
const struct timeval FAR *timeout
);
W一个参C要管Q会被系l忽略的。第二个参数是用来检查套接字可读性,也就说检查套接字上是否有数据可读Q同PW三个参数用来检查数据是否可以发出。最后一个是查是否有带外数据可读取?br>参数详细的意思请ȝMSDNQ这里限于篇q不详细解释了?br>最后一个参数是用来讄select{待多久的,是个l构Q?br>

struct timeval {
long tv_sec; // seconds
long tv_usec; // and microseconds
};
如果这个结构设|ؓ(0,0)Q那么select函数会马上返回?br>说了q么久,select的作用到底是什么?
他的作用是Q防止在在阻塞模式的套接字里被锁死,避免在非d套接字里重复查WSAEWOULDBLOCK错误?br>他的工作程如下Q?br>1Q用FD_ZERO宏来初始化我们感兴趣的fd_setQ也是select函数的第二三四个参数?br>2Q用FD_SET宏来套接字句柄分配l相应的fd_set?br>3Q调用select函数?br>4Q用FD_ISSET对套接字句柄q行查,如果我们所x的那个套接字句柄仍然在开始分配的那个fd_set里,那么说明马上可以q行相应的IO操作。比如一个分配给selectW一个参数的套接字句柄在selectq回后仍然在selectW一个参数的fd_set里,那么说明当前数据已经来了Q马上可以读取成功而不会被d?br>
下面l出一个简单的select模型的服务端套接字?br>
#include “iostream.h”
#include “winsock2.h”
#include “windows.h”


#define InternetAddr "127.0.0.1"
#define iPort 5055

#pragma comment(lib, "ws2_32.lib")


void main()
{
    WSADATA wsa;
    WSAStartup(MAKEWORD(2,2), &wsa);
    
    SOCKET fdServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(InternetAddr);
    server.sin_port = htons(iPort);
    
    int ret = bind(fdServer, (sockaddr*)&server, sizeof(server));
    ret = listen(fdServer, 4);


    SOCKET AcceptSocket;
    fd_set fdread;
    timeval tv;
    int nSize;

    while(1)
    {
        
        FD_ZERO(&fdread);//初始化fd_set
        FD_SET(fdServer, &fdread);//分配套接字句柄到相应的fd_set
        
        
        tv.tv_sec = 2;//q里我们打算让select{待两秒后返回,避免被锁死,也避免马上返?br>        tv.tv_usec = 0;
        
        select(0, &fdread, NULL, NULL, &tv);
        
        nSize = sizeof(server);
        if (FD_ISSET(fdServer, &fdread))//如果套接字句柄还在fd_set里,说明客户端已l有connect的请求发q来了,马上可以accept成功
        {
            AcceptSocket = accept(fdServer,( sockaddr*) &server, &nSize);
            break;
        }
        
        else//q没有客L的connecthQ我们可以去做别的事Q避免像没有用select方式的阻塞套接字E序被锁ȝ情况Q如果没用select,当程序运行到accept的时候客L恰好没有connecthQ那么程序就会被锁死Q做不了M事情
        {
            //do something
            ::MessageBox(NULL, "waiting...", "recv", MB_ICONINFORMATION);//别的事做完后Ql去查是否有客户端连接请?br>        }
    }

    char buffer[128];
    ZeroMemory(buffer, 128);

    ret = recv(AcceptSocket,buffer,128,0);//q里同样可以用selectQ用法和上面一?br>
    ::MessageBox(NULL, buffer, "recv", MB_ICONINFORMATION);

    closesocket(AcceptSocket);
    WSACleanup();
    
    return;

}

基本上就q样Q个人感觉select模型用处不是很大Q我只用q一ơ,d写端口扫描器的时候用select来检查超时?br>感觉讲得不是很清楚,虽然东西我很明白Q但是要讲解出来讲解得很清楚真不Ҏ?br>不知道大家能不能看懂Q如果看得过E中有什么问题就问吧?br>

]]>
WinSock学习W记http://www.shnenglu.com/xpzhou/archive/2007/04/25/22785.html榕树?/dc:creator>榕树?/author>Wed, 25 Apr 2007 01:08:00 GMThttp://www.shnenglu.com/xpzhou/archive/2007/04/25/22785.htmlhttp://www.shnenglu.com/xpzhou/comments/22785.htmlhttp://www.shnenglu.com/xpzhou/archive/2007/04/25/22785.html#Feedback1http://www.shnenglu.com/xpzhou/comments/commentRss/22785.htmlhttp://www.shnenglu.com/xpzhou/services/trackbacks/22785.html与socket有关的一些函Cl?br>
1、读取当前错误|每次发生错误Ӟ如果要对具体问题q行处理Q那么就应该调用q个函数取得错误代码?
      int  WSAGetLastError(void );
#define h_errno   WSAGetLastError()
错误D自己阅读Winsock2.h?br>
2、将L的unsigned longD{换ؓ|络字节序(32?Qؓ什么要q样做呢Q因Z同的计算Z用不同的字节序存储数据。因此Q何从Winsock函数对IP地址和端口号的引用和传给Winsock函数的IP地址和端口号均时按照|络序l织的?br>
      u_long  htonl(u_long hostlong);
举例Qhtonl(0)=0
htonl(80)= 1342177280
3、将unsigned longC|络字节序转换位主机字节顺序,是上面函数的逆函数?
      u_long  ntohl(u_long netlong);
举例Qntohl(0)=0
ntohl(1342177280)= 80
4、将L的unsigned shortD{换ؓ|络字节序(16?Q原因同2Q?
      u_short  htons(u_short hostshort);
举例Qhtonl(0)=0
htonl(80)= 20480
5、将unsigned shortC|络字节序转换位主机字节顺序,是上面函数的逆函数?
      u_short  ntohs(u_short netshort);
举例Qntohs(0)=0
ntohsl(20480)= 80
6、将用点分割的IP地址转换位一个in_addrl构的地址Q这个结构的定义见笔?一)Q实际上是一个unsigned long倹{计机内部处理IP地址可是不认识如192.1.8.84之类的数据?
      unsigned long  inet_addr( const char FAR * cp );
举例Qinet_addr("192.1.8.84")=1409810880
inet_addr("127.0.0.1")= 16777343
如果发生错误Q函数返回INADDR_NONE倹{?br>
7、将|络地址转换位用点分割的IP地址Q是上面函数的逆函数?
      char FAR *  inet_ntoa( struct in_addr in );
举例Qchar * ipaddr=NULL;
char addr[20];
in_addr inaddr;
inaddr. s_addr=16777343;
ipaddr= inet_ntoa(inaddr);
strcpy(addr,ipaddr); 
q样addr的值就变ؓ127.0.0.1?br>注意意不要修改返回值或者进行释攑֊作。如果函数失败就会返回NULL倹{?br>
8、获取套接字的本地地址l构Q?
      int  getsockname(SOCKET s, struct sockaddr FAR * name, int FAR * namelen );
s为套接字
name为函数调用后获得的地址?
namelen为缓冲区的大?
9、获取与套接字相q的端地址l构Q?br>
      int  getpeername(SOCKET s, struct sockaddr FAR * name, int FAR * namelen );
s为套接字
name为函数调用后获得的端地址?
namelen为缓冲区的大?
10、获取计机名:
      int  gethostname( char FAR * name, int namelen );
name是存放计机名的~冲?
namelen是缓冲区的大?
用法Q?
char szName[255];
memset(szName,0,255);
if(gethostname(szName,255)==SOCKET_ERROR)
{
//错误处理
}
q回gؓQszNmae="xiaojin"
11、根据计机名获取主机地址Q?
      struct hostent FAR *  gethostbyname( const char FAR * name );
name机名?
用法Q?
hostent * host;
char* ip;
host= gethostbyname("xiaojin");
if(host->h_addr_list[0])
{
struct in_addr addr;
memmove(&addr, host->h_addr_list[0]Q?);
//获得标准IP地址
ip=inet_ ntoa (addr);
}
q回gؓQhostent->h_name="xiaojin"
hostent->h_addrtype=2    //AF_INET
hostent->length=4
ip="127.0.0.1"
Winsock 的I/O操作Q?/strong>

1?两种I/O模式
  • d模式Q执行I/O操作完成前会一直进行等待,不会控制权交给E序。套接字 默认为阻塞模式。可以通过多线E技术进行处理?
  • 非阻塞模式:执行I/O操作ӞWinsock函数会返回ƈ交出控制权。这U模式?h比较复杂Q因为函数在没有q行完成p行返回,会不断地q回 WSAEWOULDBLOCK错误。但功能强大?/li>
Z解决q个问题Q提Zq行I/O操作的一些I/O模型,下面介绍最常见的三U:

2、select模型Q?br>
  通过调用select函数可以定一个或多个套接字的状态,判断套接字上是否有数据,?br>者能否向一个套接字写入数据?
      int  select( int nfds, fd_set FAR * readfds, fd_set FAR * writefds, 
fd_set FAR *exceptfds, const struct timeval FAR * timeout );
◆先来看看涉及到的结构的定义Q?br>a?d_setl构Q?br>
#define FD_SETSIZE 64?
typedef struct fd_set {
u_int fd_count; /* how many are SET? */
SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */
} fd_set;      
fd_count为已讑֮socket的数?br>fd_array为socket列表QFD_SETSIZE为最大socket数量Q徏议不于64。这是微软徏
议的?br>
B、timevall构Q?
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
tv_sec为时间的U倹{?br>tv_usec为时间的毫秒倹{?br>q个l构主要是设|select()函数的等待|如果该l构讄?0,0)Q则select()函数
会立卌回?br>
◆再来看看select函数各参数的作用Q?
  1. nfdsQ没有Q何用处,主要用来q行pȝ兼容用,一般设|ؓ0?br>
  2. readfdsQ等待可L检查的套接字组?br>
  3. writefdsQ等待可写性检查的套接字组?br>
  4. exceptfdsQ等待错误检查的套接字组?br>
  5. timeoutQ超时时间?br>
  6. 函数p|的返回|调用p|q回SOCKET_ERROR,时q回0?/li>
readfds、writefds、exceptfds三个变量臛_有一个不为空Q同时这个不为空的套接字l?br>U至有一个socketQ道理很单,否则要selectq什么呢?举例Q测试一个套接字是否可读Q?
fd_set fdread;
//FD_ZERO定义
// #define FD_ZERO(set) (((fd_set FAR *)(set))->fd_count=0)
FD_ZERO(&fdread);
FD_SET(s,&fdread)Q?//加入套接字,详细定义Lwinsock2.h
if(select(0,%fdread,NULL,NULL,NULL)>0
{
//成功
if(FD_ISSET(s,&fread) //是否存在fread中,详细定义Lwinsock2.h
{
//是可ȝ
}
}

◆I/O操作函数Q主要用于获取与套接字相关的操作参数?

 int  ioctlsocket(SOCKET s, long cmd, u_long FAR * argp );     
s为I/O操作的套接字?br>cmd为对套接字的操作命o?br>argp为命令所带参数的指针?br>
常见的命令:
//定套接字自动读入的数据?
#define FIONREAD _IOR(''''f'''', 127, u_long) /* get # bytes to read */
//允许或禁止套接字的非d模式Q允ؓ?Q禁止ؓ0
#define FIONBIO _IOW(''''f'''', 126, u_long) /* set/clear non-blocking i/o */
//定是否所有带外数据都已被d
#define SIOCATMARK _IOR(''''s'''', 7, u_long) /* at oob mark? */
3、WSAAsynSelect模型Q?br>WSAAsynSelect模型也是一个常用的异步I/O模型。应用程序可以在一个套接字上接收以
WINDOWS消息为基的网l事仉知。该模型的实现方法是通过调用WSAAsynSelect?br>?自动套接字讄为非d模式Qƈ向WINDOWS注册一个或多个|络旉Qƈ提供一
个通知时用的H口句柄。当注册的事件发生时Q对应的H口收C个基于消息的通知?br>
      int  WSAAsyncSelect( SOCKET s, HWND hWnd, u_int wMsg, long lEvent);       
s为需要事仉知的套接字
hWnd为接收消息的H口句柄
wMsg接收的消?br>lEvent为掩码,指定应用E序感兴的|络事gl合Q主要如下:
#define FD_READ_BIT 0
#define FD_READ (1 << FD_READ_BIT)
#define FD_WRITE_BIT 1
#define FD_WRITE (1 << FD_WRITE_BIT)
#define FD_OOB_BIT 2
#define FD_OOB (1 << FD_OOB_BIT)
#define FD_ACCEPT_BIT 3
#define FD_ACCEPT (1 << FD_ACCEPT_BIT)
#define FD_CONNECT_BIT 4
#define FD_CONNECT (1 << FD_CONNECT_BIT)
#define FD_CLOSE_BIT 5
#define FD_CLOSE (1 << FD_CLOSE_BIT)
用法Q要接收d通知Q?
int nResult= WSAAsyncSelect(s,hWnd,wMsg,FD_READ|FD_WRITE)Q?
if(nResult==SOCKET_ERROR)
{
//错误处理
}
取消通知Q?br>
      int nResult= WSAAsyncSelect(s,hWnd,0Q?)Q?
当应用程序窗口hWnd收到消息ӞwMsg.wParam参数标识了套接字QlParam的低字标?br>了网l事Ӟ高字则包含错误代码?br>
4、WSAEventSelect模型
WSAEventSelect模型cMWSAAsynSelect模型Q但最主要的区别是|络事g发生时会被发
送到一个事件对象句柄,而不是发送到一个窗口?br>
使用步骤如下Q?br>a?创徏事g对象来接收网l事Ӟ
#define WSAEVENT HANDLE
#define LPWSAEVENT LPHANDLE
WSAEVENT WSACreateEvent( void );
该函数的q回gؓ一个事件对象句柄,它具有两U工作状态:已传?signaled)和未传信
(nonsignaled)以及两种工作模式Qh工重?manual reset)和自动重?auto reset)。默认未
未传信的工作状态和人工重设模式?br>
b、将事g对象与套接字兌Q同时注册事Ӟ使事件对象的工作状态从未传信{变未
已传信?br>
      int  WSAEventSelect( SOCKET s,WSAEVENT hEventObject,long lNetworkEvents );  
s为套接字
hEventObject为刚才创建的事g对象句柄
lNetworkEvents为掩码,定义如上面所q?br>
c、I/O处理后,讄事g对象为未传信
BOOL WSAResetEvent( WSAEVENT hEvent );

HeventZ件对?br>
成功q回TRUEQ失败返回FALSE?br>
d、等待网l事件来触发事g句柄的工作状态:

DWORD WSAWaitForMultipleEvents( DWORD cEvents,
const WSAEVENT FAR * lphEvents, BOOL fWaitAll,
DWORD dwTimeout, BOOL fAlertable );

lpEventZ件句柄数l的指针
cEventZؓ事g句柄的数目,其最大gؓWSA_MAXIMUM_WAIT_EVENTS 
fWaitAll指定{待cdQTRUEQ当lphEvent数组重所有事件对象同时有信号时返回;
FALSEQQ一事g有信号就q回?br>dwTimeout为等待超Ӟ毫秒Q?br>fAlertable为指定函数返回时是否执行完成例程

对事件数l中的事件进行引用时Q应该用WSAWaitForMultipleEvents的返回|减去
预声明值WSA_WAIT_EVENT_0Q得到具体的引用倹{例如:

nIndex=WSAWaitForMultipleEvents(…);
MyEvent=EventArray[Index- WSA_WAIT_EVENT_0];

e、判断网l事件类型:

int WSAEnumNetworkEvents( SOCKET s,
WSAEVENT hEventObject, LPWSANETWORKEVENTS lpNetworkEvents );

s为套接字
hEventObject为需要重讄事g对象
lpNetworkEvents录网l事件和错误代码Q其l构定义如下Q?/p>

typedef struct _WSANETWORKEVENTS {
long lNetworkEvents;
int iErrorCode[FD_MAX_EVENTS];
} WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;

f、关闭事件对象句柄:

BOOL WSACloseEvent(WSAEVENT hEvent);

调用成功q回TRUEQ否则返回FALSE?br>



]]>中国黑客l织与h物名单完全档案(转蝲Q?http://www.shnenglu.com/xpzhou/archive/2007/04/23/22679.html榕树?/dc:creator>榕树?/author>Mon, 23 Apr 2007 14:16:00 GMThttp://www.shnenglu.com/xpzhou/archive/2007/04/23/22679.htmlhttp://www.shnenglu.com/xpzhou/comments/22679.htmlhttp://www.shnenglu.com/xpzhou/archive/2007/04/23/22679.html#Feedback0http://www.shnenglu.com/xpzhou/comments/commentRss/22679.htmlhttp://www.shnenglu.com/xpzhou/services/trackbacks/22679.html著名黑客l织

先介l零三年之前的组l?/strong>

安全焦点 http://www.xfocus.net/

1999q??6日由xundi创立,创始有quack和casper。后来stardust,isno,glacier,alert7,benjurry,blackhole,eyas,flashsky,funnywei,refdom,tombkeeper,watercloud,wollf{h也加入了q来。站点主风g向是很简单。而该l织目前已经成ؓ国内最权威的信息安全站点,也是最接近世界的一个国内组l。目前国内一些技术性比较强的文章都׃者亲自提交到该网站,而国内一些知名的技术属一属二的高手都会去q里的论坛。讨论技术的氛围q可以。而且一些网l安全公怹xq里的论坛。现在流行的著名扫描工具x-scan的作者就是该l织的成员。从2002q开始,每年都D办一ơ信息安全峰会,吸引了国内外众多知名|络安全专家x参加。会议涉及众多领域,备受x。创造了良好的学术交氛围。在此祝愿这个组l越走越好?/p>

中国U客联盟Q已解散Qhttp://www.cnhonker.com/

借这个机会要说明一下,只有q个U客联盟才配的上是真正的U客联盟Qƈ不是因ؓ他申请了什么专利,而是在大家的gQ只有他才只真正的红客联盟。这个组l是由lion?000q?2月组建的。曾?001q带领众多会员参与中黑客大战,而名?#8220;江湖”。不q这个时代早已逝去Q激情的往事也跟着逝去Q留lh们的只有回忆。在2005q的最后一天,lion在主上宣布正式解散。或许很多h难以理解吧。不q这也自有h家的道理。现在外面有N个红盟,我不屑于d注他们。在此祝lion,bkbll{h。对sharpwinner我就懒的说什么了?/p>

中国鹰派 http://www.chinawill.com/

与红客联盟一P都是2000q末创立Qƈ且在2001q参与了中美黑客大战。站长万涛也是早期的l色兵团成员。ƈ且也参与了在2000q前的几ơ网l战争。至这个组l依然没有倒下。近几年中ƈ没有什么大的事件发生。所以很多h对他都已l没有了什么印象。希望他们越走越好?/p>

邪恶八进?http://www.eviloctal.com/

2002q由冰血情(从他的BLOG看出来,他是咱桂林h)创立Q当时是以小l模式运营的Q而发展到现在已经成ؓ一?0多h的信息安全团队。主做的很单,但论坛内定w怸富,涉及领域众多Q在下经常去那里下蝲学术资料Q论坛管理的是我所见过的论坛中最好的。而且讨论氛围也很不错。鄙Z那里的几个核心成员有所接触Q都是比较热心的Q而且技术都是比较强的。祝愿这个组l越办越好。我对这个团队的发展充满期望?/p>

qd旅团 http://www.ph4nt0m.org/

2001q创立,发展到现在组l成员已l达?0人,q期l织推出了WIKIq_Qhttp://www.secwiki.comQ,内容涉及无线|络Q病毒与反病毒,以及黑客技术等众多领域。所有的朋友都可以到那里L鸦?002q开放了论坛Q目前论坛的技术讨论氛围还是可以的Q而且热心Z是很多的。相信这个组l也能走下去?/p>

白细?whitecell) http://www.whitecell.org/

2001q创立的一个纯技术交站炏V当时核心成员有sinisterQ无花果{hQ都是国内著名的高手。在2002q后关闭了Q而最q它由回来了。主与论坛依然都很单。希望这ơ回归会带给大家新的气象?/p>

中华安全|?http://www.safechina.net/

2001q?月创立,l过了几ơ改版后Q队伍也发展的比较大Q我所熟悉的有yellow,Phoenix{h。到现在Q这个网站还在改版中Q不q论坛依然开放,在这里还是有讨论I间的。组l内的h技术也都是不错的。希望这ơ改版后会有大的变化Q)?/p>

W八军团

2000q左右由陈三公子l织成立Q后l过多次改版。成Z一个VIP制的站点Q资源收集量q是不错的。鄙人经常去那里找代理服务器Q更新的速度q是可以的。论坛里讨论气氛不是很热烈。希望今后发展的会更好?/p>

来说说这两年成立的黑客组l?/p>

BCT http://www.cnbct.org/

2004q底成立的一个专门挖掘脚本漏z的l织。已l发展了一q了。在下与H4K_B4N,fpx到是有些接触。感觉这个组l是不错的,虽然没有做什么媄响力大的事情Q但是这U默默研I技术的_q是值得发扬的,与那些招摇的比,要好多了。网站上攉了一些漏z资料,q点到是做的比较好。希望l努力,发展的越来越好?/p>

火狐技术联?http://www.wrsky.com/

2004q徏立的一个组l,致力于破解Y件的l织。对于他们组l现在很有争议,也曾l一度遭受到猛烈的拒l服务攻击,造成|站瘫痪长大数月Q到现在是一个论坛系l。对于这个组l,到目前ؓ止还是有争议。希望能早日qx?/p>

黑客技?http://www.hackart.org/

2003q成立的l织Q之前用的是乔客的整站E序Q后来就关闭了。也是最q重开的站点,使用的是论坛pȝQ在下与那里的版主风般的男h和Jambalaya 是好朋友。他们的技术还是不错的。现在论坛h气虽然不怎么高,但显然是老站重开Q知道的不多Q希望日后可以恢复元气,l箋发展下去?/p>

国内三大商业黑客站点

黑客基地

http://www.hackbase.com/ 2003q成立。站镉K哥?/p>

黑鹰基地 http://www.3800cc.com/ q特创立的商业黑客站点?/p>

华夏黑客同盟 http://www.77169.com/ 2004q由怪狗创立的站炏V?/p>

其实黑客l织多的C胜数Q我也只是D几个著名的而已?/p>

黑客人物

下面来说说h物吧Q现在的黑客来多Q我重点介绍那些专著于系l与漏洞的高手,当然他们对入侵也是有所造诣的。注意,qƈ不是排名Q不是第一个就是最厉害Q而最后一个是q里面技术最差的Q如果这h错了。因为有时候想着费劲所以就q入一下牛人的BLOG以及一些论坛去看,q样可以容易记hQ知道写谁。先从这里找http://www.0x557.org/~kkqq/ 然后在从安全焦点的文章和论坛里还有绿盟去找?/p>

alert7 QQ:415451 email:alert7@xfocus.org http://blog.xfocus.net/index.php?blogId=12 安全焦点核心成员Q曾l在补天的。精通linux操作pȝQ对于linux下的漏洞很有研究?/p>

baozi(fatb) QQ:48448355 http://blog.xfocus.net/index.php?blogId=3 对windows与linux下的入R很精通?/p>

CoolQ QQ:49462335 http://coolq.blogdriver.com/coolq/index.html email:qufuping@ercist.iscas.ac.cn 我也是在安全焦点05q的C上认识的他,是中U院软g研究所的学生,对于linux非常有研I。在最后一期的Phrack杂志上有他的文章《Hacking Grub for fun and profit》也是在q期杂志中发表文章的三位中国Z一。另外著作还有《ways to hide files in ext2/3filesystem?/p>

bkbll(dumplogin) email:bkbll@cnhonker.com http://blog.0x557.org/dumplogin/ 原中国红客联盟核心成员,与lion曄一起参加过中美黑客大战。对windows与linux都很有研I。著作有《POSIX子系l权限提升漏z的分析?/p>

flashsky QQ:16202253 email:flashsky@xfocus.org http://www.qjclub.net/blog/user1/497/index.html 安全焦点核心成员。精通windows操作pȝ上的~冲区溢出,当年是他一q公布了微Y的N个漏z,微Y此q谴责过安全焦点。现p于启明星辰?/p>

Flier Lu email:flier@nsfocus.com http://flier_lu.blogcn.com/ l盟的高手,_Nwindows操作pȝ内核Q著作有《MS.Net CLR扩展PEl构分》《自动验?Windows NT pȝ服务描述表》《CLR 中代码访问安全检实现原理》等{?/p>

funnywei QQ:25044885 email:funnywei@xfocus.org http://blog.xfocus.net/index.php?blogId=28 安全焦点核心成员Q熟悉windows操作pȝ。著作有《WindowsXpSp2溢出保护?/p>

glacier QQ:1937435 email:glacier@xfocus.org http://blog.xfocus.net/index.php?blogId=15 安全焦点核心成员Q精通windows~程Q网l编E,delphi{等。是冰河木马以及著名扫描软gx-scan的作者?

icbm email:icbm@0x557.org http://blog.0x557.org/icbm/ _Nlinux操作pȝ内核以及漏洞。就职于启明星辰。翻译过文章《Building ptrace injecting shellcodes》是《浅析Linux内核漏洞》的作者?/p>

killer QQ:6362602 email:killer@xfocus.org http://blog.xfocus.net/index.php?blogId=2 安全焦点灌水区版丅R精通逆向工程Q程序破解?/p>

pjf QQ:85863144 http://pjf.blogcn.com/ 著名的检工具icesword(冰刃)的作者。很多程序员以及~写rootkit的高手以l过它的工具ؓ目标。熟悉windows操作pȝ内核?/p>

refdom email:refdom@xfocus.org http://blog.xfocus.net/index.php?blogId=11 安全焦点核心成员Q《反垃圾邮g技术解析》的作者。似乎曾l是U客联盟的h?/p>

stardust QQ:6269692 email:stardust@xfocus.org http://blog.xfocus.net/index.php?blogId=7 安全焦点核心成员。熟悉linux,_NIDS。著作有《从漏洞及攻d析到NIDS规则设计》《Bro NIDS的规则》《Snort 2.x数据区搜索规则选项的改q》《Bro NIDS的安装与配置?/p>

sunwear QQ:47347 email:shellcoder@163.com http://blog.csdn.net/sunwear/ 邪恶八进制核心成员。精通windows操作pȝ内核。著作有《利用NTLDRq入RING0的方法及MGF病毒技术分析笔记》《浅析本机API》《智能ABC输入法溢出分析?/p>

swan email:swan@xfocus.org http://blog.0x557.org/swan/ 对缓冲区溢出漏洞很有研究。最q的ms05051 Microsoft Windows DTC 漏洞的exploit作者就是他?/p>

tombkeeper QQ:644909 http://blog.xfocus.net/index.php?blogId=9 安全焦点核心成员。精通windows操作pȝ内核。著作有《用Bochs调试NTLDR》《修改Windows SMB相关服务的默认端口》等{。在焦点C上见到过他,很帅?/p>

watercloud http://blog.xfocus.net/index.php?blogId=6 安全焦点核心成员。精通windows,linux操作pȝ。著作有《手工打造微型Win32可执行文件》《溢出利用程序和~程语言大杂烩》《RSA法基础->实践?/p>

zwell email:suei8423@163.com http://blog.donews.com/zwell NB联盟核心成员。精通windows操作pȝQ著作有《安全稳定的实现q线E监控》《一U新的穿透防火墙的数据传输技术?/p>

zzzevazzz QQ:49322630 http://zzzevazzz.bokee.com/index.html qd旅团核心成员。原灰色轨迹的h。精通windows操作pȝ内核。著作有《Do All in Cmd Shell》《无驱动执行ring0代码》等{?/p>

榕 http://www.netxeyes.org 光Qؕ刀Qh雪及命o行SQL注入工具的作者。中国第二代黑客?/p>

lion QQ:21509 email:lion@cnhonker.com http://www.cnhonker.com 原中国红客联盟站长,对缓冲区溢出很有研究。精通linux.windows.

isno QQ:1070681 email:isno@xfocus.org 安全焦点核心成员Q精通缓冲区溢出漏洞。webdav溢出E序的作者。写qIDQQIDA漏洞溢出的分析等{?/p>

sinister QQ:3350124 email:sinister@whitecell.org 白细胞成员。精通windows内核QAIX。著作有《NT 内核的进E调度分析笔记》《NT 下动态切换进E分析笔记》《AIX 内核的虚拟文件系l框架》《AIX 内核的文件操作流E?/p>

袁哥 email:yuange@nsfocus.com 现就职于中联l盟公司。精通windows操作pȝ内核以及漏洞利用?/p>

warning3 email:warning3@nsfocus.com msn:warning3@hotmail.com _Nlinux unix内核及漏z。现p于中联绿盟公司。著作有《Heap/BSS 溢出机理分析?/p>

SoBeIt QQ:27324838 email:kinvis@hotmail.com _Nwindows~程以及pȝ内核q有溢出。著作有《Windows内核调试器原理浅析》,《挂钩Windows API》等{翻译过《在NTpd操作pȝ里让自己“消失”?/p>

xhacker QQ:66680800 _N渗透入侵以及脚本入c著作有《详q虚拟网站的权限H破及防范》,《如何利用黑客技术跟tƈ分析一名目标h物?/p>

eyas QQ:320236 email:eyas@xfocus.org 安全焦点核心成员Q熟悉windows操作pȝQwindows~程。著作有《NTq_拨号q接密码恢复原理》,《WS_FTP FTPD STAT命oq程溢出分析?/p>

孤独剑客 QQ:5385757 email:Janker@Hackbase.Com Http://Www.Janker.Org _N编E。以及入侉|术。winshell的作者。中国第二代黑客?/p>

sunx QQ:239670 http://www.sunx.org Ҏ出有研究Q写qIDA漏洞和printer漏洞的溢出程序。精通汇~。著作很多?/p>

analysist QQ:20116789 _N数据库与脚本入c早q对跨站脚本以及很多脚本漏洞很有研究。著作有《跨站脚本执行漏z详解》,《BBS2000和BBS3000所存在的安全隐患?/p>

Frankie http://cnns.net _Nwindows操作pȝQ与linux。中国第一代黑客?/p>

rootshell(fzk) QQ:1734398 http://www.ns-one.com _Nwindows操作pȝQ熟悉缓冲区溢出漏洞。老一代的黑客。著作有《最q发现的一个Distributed File System服务q程溢出问题》?/p>

PP QQ:82928 _Nwindows操作pȝ。名aQ?font style="BACKGROUND-COLOR: #ffff00">如果想飞得高Q就该把地^U忘?/font>?/p>

tianxing OICQ:911189 |站:http://www.tianxing.org/ _Nwindows操作pȝ与漏z利用。RPC漏洞利用E序以及|络刺客,|络卫兵的作者?/p>

grip2 QQ:1007270 _Nlinux操作pȝ。著作有《一个Linux病毒原型分析?/p>

san QQ:56941 _Nwindows操作pȝ以及linux。而且对windows CE很有研究。phrack最后一期的杂志中,刊登q他的文章?/p>

hume QQ:8709369 _N汇~以及windows操作pȝ。著作有《SEH in ASM 的研I?/p>

backend email:backend@antionline.org _Nlinux操作pȝ。翻译过很多文章Q是l盟的高手。不q已l几q没见在|络上游C。到是现实中偶尔看到他?/p>

Adam QQ:15898 email:adam@nsfocus.com l盟的高手,windows安全版版丅R精通windows操作pȝ?/p>

ipxodi QQ:16175535 email:ipxodi@nsfocus.com 很长旉没看见他了。精通windows操作pȝ以及~冲区溢出。著作有《windowpȝ下的堆栈溢出》《Windows 2000~冲区溢出入门》。这些文章都是造福了很多后辈的?/p>

zer9 QQ:573369 email:zer9@21cn.com 也是很长旉没见C。早期写q不文章和工具。也是老一辈的革命家?/p>

whg QQ:312016 email:whg0001@163.com http://WWW.CNASM.COM 不知道算不算白细胞的成员Q呵c病毒高手。精通汇~。写q不YӞ例如lan下sniff QQ的工具以及sniff工具{等Q可以到他的主页上去看?/p>

lg_wu email:lgwu2000@sina.com 在绿盟论坛和安全焦点都见q,对linux_N的很。技术不一般的说?/p>

wowocock QQ:37803144 _Nwindows操作pȝ内核Q汇~。在驱动开发网以及cvc L淡写见过Q技术不一般。著作很多,但是见到的很。不知道Z么这么好的文章没{Q?/p>

baiyuanfan QQ:51449276 q小子在C上给我的印象很深。在技术上很下工夫。对windows也算有研I了。著作当然是byshell了?/p>

vxk QQ:355852911 汇编技术很,_Nwindows内核。经常在cvc论坛看到他?/p>

冰血情 QQ:124839278 邪恶八进制的创始人。中国第四代黑客。感觉这个h很不错。对他的l织比较认可。技术上面还可以?/p>

Polymorphours(shadow3) QQ:120974745白细胞成员。以前叫shadow3.好象换名字了。熟悉windows操作pȝQ以及缓冲区溢出。著作有《MS05-010许可证记录服务漏z允许执行代码的分析》《Media Player 8.0 vulnerability》等{?/p>

e4gle QQ:1949479白细胞成员。老一代的黑客。精通linuxpȝ内核以及病毒技术,~冲区溢出。著作有《程序攻d理》《Unixpȝ病毒概述》《高U缓冲溢出的使用?/p>

bingle QQ:45671342很早p识的一个兄弟了。著作不,很多都很实用?/p>

wollf QQ:228095 glacier的老婆。一定不能让他知道我是谁Q要不我死定了。她是黑客;Q美女黑客!

goodwellQ中国早期著名黑客组l-l色兵团 创始Z一?/p>

yellow QQ:12398890Q中华安全网核心成员。熟悉缓冲区溢出与windows~程?/p>

江v?QQ:741534Q曾l参加某个会议的时候见q他Q聊的还可以Q后来在焦点C时又C面。此人是反病毒方面的高手?/p>

icmbQ启明星辰linux斚w的高手。对于漏z方面很有研I。不带眼睛更漂亮…… 



]]>
VC6.0~译器参数设|?http://www.shnenglu.com/xpzhou/archive/2007/04/23/22672.html榕树?/dc:creator>榕树?/author>Mon, 23 Apr 2007 11:51:00 GMThttp://www.shnenglu.com/xpzhou/archive/2007/04/23/22672.htmlhttp://www.shnenglu.com/xpzhou/comments/22672.htmlhttp://www.shnenglu.com/xpzhou/archive/2007/04/23/22672.html#Feedback0http://www.shnenglu.com/xpzhou/comments/commentRss/22672.htmlhttp://www.shnenglu.com/xpzhou/services/trackbacks/22672.htmlVC6.0~译器参数的讄主要通过VC的菜单项Project->Settings->C/C++|完成。我们可以看到这一늚最下面Project Options中的内容Q一般如下:

/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"Debug/WritingDlgTest.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c

各个参数代表的意义,可以参考Msdn。比?nologo表示~译时不在输出窗口显C些设|(我们可以把这个参数去掉来看看效果Q等{。一般我们不会直接修改这些设|,而是通过q一|上面的Category中的各项来完?.....
Q{载-


主要通过VC的菜单项Project->Settings->C/C++|完成。我们可以看到这一늚最下面Project Options中的内容Q一般如下:

/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"Debug/WritingDlgTest.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c

各个参数代表的意义,可以参考Msdn。比?nologo表示~译时不在输出窗口显C些设|(我们可以把这个参数去掉来看看效果Q等{。一般我们不会直接修改这些设|,而是通过q一|上面的Category中的各项来完成?/font>

1) GeneralQ一些M讄?/font>

Warning level 用来控制警告信息Q其中Level 1是最严重的别;
Warnings as errors 警告信息当作错误处理;
Optimizations 代码优化Q可以在Category的Optimizations中q行更细的设|;
Generate browse info 用以生成.sbr文gQ记录类、变量等W号信息Q可以在Category的Listing Files中q行更多的设|?
Debug info 生成调试信息Q?
NoneQ不产生M调试信息Q编译比较快Q;
Line Numbers OnlyQ仅生成全局的和外部W号的调试信息到.OBJ文g?EXE文gQ减目标文件的寸Q?
C 7.0- CompatibleQ记录调试器用到的所有符号信息到.OBJ文g?EXE文gQ?
Program DatabaseQ创?PDB文g记录所有调试信息;
Program Database for "Edit & Continue"Q创?PDB文g记录所有调试信息,q且支持调试时编辑?

2) C++ Language

Pointer-to-member representation 用来讄cd?引用的先后关p:
Best-Case AlwaysQ表C在引用cM前该c肯定已l定义;
General-Purpose AlwaysQ?
Point to Any Class
Point to Single- and Multiple-Inheritance Classes
Point to Single-Inheritance Classes
Enable Exception HandlingQ进行同步的异常处理Q?
Enable Run-Time Type Information qɾ~译器增加代码在q行时进行对象类型检查;
Disable Construction Displacements 讄cL?析构函数调用虚函数问题?

3) Code Generation

Processor 表示代码指o优化Q可以ؓ80386?0486、Pentium、Pentium ProQ或者Blend表示混合以上各种优化?
Use run-time library 用以指定E序q行时用的q行时库Q有一个原则就是,一个进E不要同时用几个版本的q行时库。连接了单线E库׃支持多线E调用,q接了多U程库就要求创徏多线E的应用E序?
Single-ThreadedQ单U程Release版本Q静态连接LIBC.LIB库;
Debug Single-ThreadedQ单U程Debug版本Q静态连接LIBCD.LIB库;
MultithreadedQ多U程Release版本Q静态连接LIBCMT.LIB库;
Debug MultithreadedQ多U程Debug版本Q静态连接LIBCMTD.LIB库;
Multithreaded DLLQ动态连接MSVCRT.DLL库;
Debug Multithreaded DLLQ动态连接MSVCRTD.DLL库?
Calling convention 可以用来讑֮调用U定Q有三种Q__cdecl、__fastcall和__stdcall?br>  各种调用U定的主要区别在于:1. 函数调用Ӟ函数的参数是从左到右压入堆栈q是从右到左压入堆栈Q?. 在函数返回时Q由函数的调用者来清理压入堆栈的参数还是由函数本n来清理;3. 以及在编译时对函数名q行的命名修饎ͼ可以通过Listing Files看到各种命名修饰方式Q?
Struct member alignment 用以指定数据l构中的成员变量在内存中是按几字节对齐的Q根据计机数据ȝ的位敎ͼ不同的对齐方式存取数据的速度不一栗这个参数对数据包网l传输等应用ؓ重要Q不是存取速度问题Q而是数据位的_定义问题Q一般在E序中?pragma pack来指定?

4) Customize

Disable Language ExtensionsQ表CZ使用微Y为标准C做的语言扩展Q?
Eliminate Duplicate StringsQ主要用于字W串优化Q将字符串放到缓充池里以节省I间Q,使用q个参数Q?br>            char *sBuffer = "This is a character buffer";
            char *tBuffer = "This is a character buffer";
            sBuffer 和tBuffer指向的是同一块内存空_
Enable Function-Level Linking Q告诉编译器各个函数按打包格式~译Q?
Enables minimal rebuildQ通过保存兌信息?IDB文gQɾ~译器只Ҏ新类定义改动q的源文件进行重~译Q提高编译速度Q?
Enable Incremental CompilationQ同样通过.IDB文g保存的信息,只重~译最新改动过的函敎ͼ
Suppress Startup Banner and Information MessagesQ用以控制参数是否在outputH口输出?/font>


5) Listing Files

Generate browse info 上面已经提到q。这里可以进行更多的讄?
Exclude Local Variables from Browse Info 表示是否局部变量的信息攑ֈ.SBR文g中?
Listing file type 可以讄生成的列表信息文件的内容Q?
Assembly-Only Listing 仅生成汇~代码文Ӟ.ASM扩展名)Q?
Assembly With Machine Code 生成机器代码和汇~代码文Ӟ.COD扩展名)Q?
Assembly With Source Code 生成源代码和汇编代码文gQ?ASM扩展名)Q?
Assembly, Machine Code, and Source 生成机器码、源代码和汇~代码文Ӟ.COD扩展名)?
Listing file name 生成的信息文件的路径Q一般ؓDebug或Release目录下,生成的文件名自动取源文g的文件名?

6) Optimizations 代码优化讄?/font>

Maximize Speed 生成最快速的代码Q?
Minimize Size 生成最尺寸的E序Q?
Customize 定制优化。定制的内容包括Q?
Assume No AliasingQ不使用别名Q提高速度Q;
Assume Aliasing Across Function CallsQ仅函数内部不用别名;
Global OptimizationsQ全局优化Q比如经常用到的变量使用寄存器保存,或者@环内的计优化,如i = -100;while( i < 0 ){i += x + y;}会被优化为i = -100;t = x + y;while( i < 0 ){i += t;}Q?
Generate Intrinsic FunctionsQ用内部函数替换一些函数调用(提高速度Q;
Improve Float ConsistencyQQ点运方面的优化Q?
Favor Small CodeQ程序(exe或dllQ尺怼化优先于代码速度优化Q?
Favor Fast CodeQ程序(exe或dllQ代码速度优化优先于尺怼化;
Frame-Pointer OmissionQ不使用帧指针,以提高函数调用速度Q?
Full OptimizationQ组合了几种参数Q以生成最快的E序代码?
Inline function expansionQ内联函数扩展的三种优化Q用内联可以节省函数调用的开销Q加快程序速度Q:
DisableQ不使用内联Q?
Only __inlineQ仅函数定义前有inline或__inline标记使用内联Q?
Any SuitableQ除了inline或__inline标记的函数外Q编译器"觉得"应该使用内联的函敎ͼ都用内联?

7) Precompiled Headers 预编译头文g的设|。用预~译可以提高重复~译的速度。VC一般将一些公q、不大变动的头文Ӟ比如afxwin.h{)集中攑ֈstdafx.h中,q一部分代码׃必每ơ都重新~译Q除非是Rebuild AllQ?/font>


8) Preprocessor 预编译处理。可以定?解除定义一些常量?/font>

Additional include directoriesQ可以指定额外的包含目录Q一般是相对于本目的目录,?.\Include?/font>


--------------------------------------------------------------------------------
q接参数的设|?br>主要通过VC的菜单项Project->Settings->Link|完成。我们可以看到这一늚最下面Project Options中的内容Q一般如下:

/nologo /subsystem:windows /incremental:yes /pdb:"Debug/WritingDlgTest.pdb" /debug /machine:I386 /out:"Debug/WritingDlgTest.exe" /pdbtype:sept

下面我们分别来看一下Category中的各项讄?/font>

1) General 一些M讄。可以设|生成的文g路径、文件名Q连接的库文Ӟ

Generate debug infoQ生成Debug信息?PDB文gQ具体格式可以在Category->Debug中设|)Q?
Ignore All Default LibrariesQ放弃所有默认的库连接;
Link IncrementallyQ通过生成. ILK文g实现递增式连接以提高后箋q接速度Q但一般这U方式下生成的文ӞEXE或DLLQ较大;
Generate MapfileQ生?MAP文g记录模块相关信息Q?
Enable ProfilingQ这个参数通常与Generate Mapfile参数同时使用Q而且如果产生Debug信息的话Q不能用.PDB文gQ而且必须用Microsoft Format?

2) Customize q里可以q行使用E序数据库文件的讄?/font>

Force File OutputQ强制生输出文ӞEXE或DLLQ;
Print Progress MessagesQ可以将q接q程中的q度信息输出到OutputH口?

3) Debug 讄是否生成调试信息Q以及调试信息的格式?/font>

Dubug infoQ格式可以有Microsoft Format、COFF FormatQCommon Object File FormatQ和Both Formats三种选择Q?
Separate TypesQ表C将Debug格式信息以独立的.PDB文g存放Q还是直接放在各个源文g?PDB文g中。选中的话Q表C采用后者的方式Q这U方式调试启动比较快?/font>


4) Input q里可以指定要连接的库文Ӟ攑ּq接的库文g。还可以增加额外的库文g目录Q一般是相对于本目的目录,?.\Lib?/font>

Force Symbol ReferencesQ可以指定连接特定符号定义的库?

5) Output 

Base Address 可以改变E序默认的基地址QEXE文g默认?x400000QDLL默认?x10000000Q,操作pȝ装蝲一个程序时L试着先从q个基地址开始?
Entry-Point Symbol 可以指定E序的入口地址Q一般ؓ一个函数名Q且必须采用__stdcall调用U定Q。一般Win32的程序,EXE的入口ؓ WinMainQDLL的入口ؓDllEntryPointQ最好让q接器自动设|程序的入口炏V默认情况下Q通过一个C的运行时库函数来实现Q控制台E序采用mainCRTStartup (或wmainCRTStartup)去调用程序的main (或wmain)函数QWindowsE序采用WinMainCRTStartup (?wWinMainCRTStartup)调用E序的WinMain (?wWinMainQ必采用__stdcall调用U定)QDLL采用_DllMainCRTStartup调用DllMain函数Q必采?__stdcall调用U定Q?
Stack allocations 用以讄E序使用的堆栈大(请用十q制Q,默认?兆字节?
Version Information 告诉q接器在EXE或DLL文g的开始部分放上版本号?

值得注意的是Q?/font>

上面各个参数是大写敏感的;
在参数后加上"-"表示该参数无效;
各个参数值选项?*"的表CZؓ该参数的默认|
可以使用右上角?Reset"按钮来恢复该늚所有默认设|?

--------------------------------------------------------------------------------
其它一些参数设|?/font>

1) Project->Settings->GeneralQ可以设|连接MFC库的方式Q静态或动态)。如果是动态连接,在MFC软g发布时不要忘了带上MFC的DLL?/font>

2) Project->Settings->DebugQ可以设|调试时q行的可执行文gQ以及命令行参数{?/font>

3) Project->Settings->Custom BuildQ可以设|编?q接成功后自动执行一些操作。比较有用的是,写COM时希望VC对编译通过的COM文g自动注册Q可以如下设|:

Description: Register COM

Commands: regsvr32 /s /c $(TargetPath)

echo regsvr32 exe.time > $(TargetDir)\$(TargetName).trg

Outputs: $(TargetDir)\$(TargetName).trg


4) Tools->Options->DirectoriesQ设|系l的Include、Library路径?/font>

--------------------------------------------------------------------------------
窍? 目中的.ncb?opt?aps?clw文g以及Debug、Release目录下的所有文仉可以删掉的?/font>



]]>
VC中基?Windows 的精定?/title><link>http://www.shnenglu.com/xpzhou/archive/2007/04/20/22426.html</link><dc:creator>榕树?/dc:creator><author>榕树?/author><pubDate>Fri, 20 Apr 2007 13:03:00 GMT</pubDate><guid>http://www.shnenglu.com/xpzhou/archive/2007/04/20/22426.html</guid><wfw:comment>http://www.shnenglu.com/xpzhou/comments/22426.html</wfw:comment><comments>http://www.shnenglu.com/xpzhou/archive/2007/04/20/22426.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/xpzhou/comments/commentRss/22426.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/xpzhou/services/trackbacks/22426.html</trackback:ping><description><![CDATA[在工业生产控制系l中Q有许多需要定时完成的操作Q如定时昄当前旉Q定时刷新屏q上的进度条Q上?wbr> 机定时向下位机发送命令和传送数据等。特别是在对控制性能要求较高的实时控制系l和数据采集pȝ中,更需要精定时操作?br>  众所周知QWindows 是基于消息机制的pȝQQ何事件的执行都是通过发送和接收消息来完成的?wbr> q样带来了一些问题,如一旦计机的CPU被某个进E占用,或系l资源紧张时Q发送到消息队列<wbr> 中的消息暂时被挂vQ得不到实时处理。因此,不能单地通过Windows消息引发一个对定时要求<wbr> 严格的事件。另外,׃在Windows中已l封装了计算机底层硬件的讉KQ所以,要想通过直接利用<wbr> 讉Kg来完成精定Ӟ也比较困难。所以在实际应用Ӟ应针对具体定时精度的要求Q采取相?应的定时Ҏ?br>  VC中提供了很多关于旉操作的函敎ͼ利用它们控制E序能够_地完成定时和计时操作。本文详l介l了<wbr> VC中基于Windows的精定时的七种方式Q如下图所C:<br><br><img src="http://www.vckbase.com/document/journal/vckbase37/images/MultiTimerDemoimg.gif" border=0><br>图一 囑փ描述 <br><br>  方式一QVC中的WM_TIMER消息映射能进行简单的旉控制。首先调用函数SetTimer()讄定时<wbr> 间隔Q如SetTimer(0,200,NULL)即ؓ讄200ms的时间间隔。然后在应用E序中增加定时响应函?wbr> OnTimer()Qƈ在该函数中添加响应的处理语句Q用来完成到辑֮时时间的操作。这U定时方法非?wbr> 单,可以实现一定的定时功能Q但其定时功能如同Sleep()函数的g时功能一P_ֺ非常低,最?wbr> 计时_ֺ仅ؓ30msQCPU占用低,且定时器消息在多d操作pȝ中的优先U很低,不能得到及时?wbr> 应,往往不能满实时控制环境下的应用。只可以用来实现诸如位图的动态显C等对定时精度要求不高的情况。如CZ工程中的Timer1?<br>  方式二:VC中用sleep()函数实现延时Q它的单位是msQ如延时2U,用sleep(2000)。精度非?wbr> 低,最计时精度仅?0msQ用sleep函数的不利处在于延时期间不能处理其他的消息,如果旉?wbr> 长,好象死ZPCPU占用率非帔RQ只能用于要求不高的延时E序中。如CZ工程中的Timer2?br>  方式三:利用COleDateTimecdCOleDateTimeSpancȝ合WINDOWS的消息处理过E来实现U延时。如CZ工程中的Timer3和Timer3_1。以下是实现2U的延时代码Q?<br>COleDateTime      start_time = COleDateTime::GetCurrentTime();<br>COleDateTimeSpan  end_time= COleDateTime::GetCurrentTime()-start_time;<br>while(end_time.GetTotalSeconds()< 2) //实现延时2U?br>{<br>MSG   msg;<br>GetMessage(&msg,NULL,0,0);<br>TranslateMessage(&msg);<br>DispatchMessage(&msg);<br>//以上四行是实现在延时或定时期间能处理其他的消息,<br>//虽然q样可以降低CPU的占有率Q?br>//但降低了延时或定时精度,实际应用中可以去掉?br>end_time = COleDateTime::GetCurrentTime()-start_time;<br>}//q样在g时的时候我们也能够处理其他的消息?nbsp;       方式四:在精度要求较高的情况下,VC中可以利用GetTickCount()函数Q该函数的返回值是<wbr>  DWORD型,表示以ms为单位的计算机启动后l历的时间间隔。精度比WM_TIMER消息映射高,在较<wbr> 短的定时中其计时误差?5msQ在较长的定时中其计时误差较低,如果定时旉太长Q就好象L一PCPU占用率非帔RQ只能用于要求不高的延时E序中。如CZ工程中的Timer4和Timer4_1。下列代码可以实?0ms的精定Ӟ<br> <pre>DWORD dwStart = GetTickCount(); DWORD dwEnd = dwStart; do { dwEnd = GetTickCount()-dwStart; }while(dwEnd <50);</pre> ZGetTickCount()函数在g时或定时期间能处理其他的消息Q可以把代码改ؓQ?br> <pre>DWORD dwStart = GetTickCount(); DWORD dwEnd = dwStart; do { MSG msg; GetMessage(&msg,NULL,0,0); TranslateMessage(&msg); DispatchMessage(&msg); dwEnd = GetTickCount()-dwStart; }while(dwEnd <50);</pre> 虽然q样可以降低CPU的占有率Qƈ在g时或定时期间也能处理其他的消息,但降低了延时或定时精度?br>  方式五:与GetTickCount()函数cM的多媒体定时器函数DWORD timeGetTime(void)Q该函数定时_?wbr> 度ؓmsU,q回从Windows启动开始经q的毫秒数。微软公司在其多媒体Windows中提供了_定时器的?wbr> 层API持,利用多媒体定时器可以很精地dpȝ的当前时_q且能在非常_的时间间隔内完成一<wbr> 个事件、函数或q程的调用。不同之处在于调用DWORD timeGetTime(void) 函数之前必须?Winmm.lib <wbr> ?Mmsystem.h d到工E中Q否则在~译时提CDWORD timeGetTime(void)函数未定义。由于用该<wbr> 函数是通过查询的方式进行定时控制的Q所以,应该建立定时循环来进行定时事件的控制。如CZ工程中的Timer5和Timer5_1?br>  方式六:使用多媒体定时器timeSetEvent()函数Q该函数定时_ֺ为msU。利用该函数可以实现周期性的函数调用。如CZ工程中的Timer6和Timer6_1。函数的原型如下Q?<br> <pre>MMRESULT timeSetEventQ?UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, WORD dwUser, UINT fuEvent Q?/pre>   该函数设|一个定时回调事Ӟ此事件可以是一个一ơ性事件或周期性事件。事件一旦被Ȁz,便调用指定的回调函数Q?wbr> 成功后返回事件的标识W代码,否则q回NULL。函数的参数说明如下Q?br> <pre>uDelayQ以毫秒指定事g的周期? UresolutionQ以毫秒指定延时的精度,数D定时器事g分L率越高。缺省gؓ1ms? LpTimeProcQ指向一个回调函数? DwUserQ存攄h供的回调数据? FuEventQ指定定时器事gcdQ? TIME_ONESHOTQuDelay毫秒后只产生一ơ事? TIME_PERIODIC Q每隔uDelay毫秒周期性地产生事g? </pre>   具体应用Ӟ可以通过调用timeSetEvent()函数Q将需要周期性执行的d定义在LpTimeProc回调函数<wbr> ?如:定时采样、控制等)Q从而完成所需处理的事件。需要注意的是,d处理的时间不能大于周期间隔时间。另外,在定时器使用完毕后,<wbr> 应及时调用timeKillEvent()之释放?<br>  方式七:对于_度要求更高的定时操作Q则应该使用QueryPerformanceFrequency()?wbr> QueryPerformanceCounter()函数。这两个函数是VC提供的仅供Windows 95及其后箋版本使用的精时间函敎ͼq要求计机从硬件上支持_定时器。如CZ工程中的Timer7、Timer7_1、Timer7_2、Timer7_3?br>QueryPerformanceFrequency()函数和QueryPerformanceCounter()函数的原型如下:<br> <pre>BOOL QueryPerformanceFrequency(LARGE_INTEGER QlpFrequency); BOOL QueryPerformanceCounter(LARGE_INTEGER QlpCount);</pre>   数据cdARGE_INTEGER既可以是一?字节长的整型敎ͼ也可以是两个4字节长的整型数的联合l构Q?wbr> 其具体用法根据编译器是否支持64位而定。该cd的定义如下:<br> <pre>typedef union _LARGE_INTEGER { struct { DWORD LowPart ;// 4字节整型? LONG HighPart;// 4字节整型? }; LONGLONG QuadPart ;// 8字节整型? }LARGE_INTEGER ;</pre>   在进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的旉频率Q?wbr> 然后在需要严格定时的事g发生之前和发生之后分别调用QueryPerformanceCounter()函数Q利用两ơ获得的计数之差及时钟频率,计算Z件经<wbr> 历的_旉。下列代码实?ms的精定Ӟ<br> <pre>LARGE_INTEGER litmp; LONGLONG QPart1,QPart2; double dfMinus, dfFreq, dfTim; QueryPerformanceFrequency(&litmp); dfFreq = (double)litmp.QuadPart;// 获得计数器的旉频率 QueryPerformanceCounter(&litmp); QPart1 = litmp.QuadPart;// 获得初始? do { QueryPerformanceCounter(&litmp); QPart2 = litmp.QuadPart;//获得中止? dfMinus = (double)(QPart2-QPart1); dfTim = dfMinus / dfFreq;// 获得对应的时间|单位为秒 }while(dfTim<0.001);</pre>   其定时误差不过1微秒Q精度与CPU{机器配|有兟?下面的程序用来测试函数Sleep(100)的精持l时_<br> <pre>LARGE_INTEGER litmp; LONGLONG QPart1,QPart2; double dfMinus, dfFreq, dfTim; QueryPerformanceFrequency(&litmp); dfFreq = (double)litmp.QuadPart;// 获得计数器的旉频率 QueryPerformanceCounter(&litmp); QPart1 = litmp.QuadPart;// 获得初始? Sleep(100); QueryPerformanceCounter(&litmp); QPart2 = litmp.QuadPart;//获得中止? dfMinus = (double)(QPart2-QPart1); dfTim = dfMinus / dfFreq;// 获得对应的时间|单位为秒 </pre>   ׃Sleep()函数自n的误差,上述E序每次执行的结果都会有微小误差。下列代码实?微秒的精定Ӟ<br> <pre>LARGE_INTEGER litmp; LONGLONG QPart1,QPart2; double dfMinus, dfFreq, dfTim; QueryPerformanceFrequency(&litmp); dfFreq = (double)litmp.QuadPart;// 获得计数器的旉频率 QueryPerformanceCounter(&litmp); QPart1 = litmp.QuadPart;// 获得初始? do { QueryPerformanceCounter(&litmp); QPart2 = litmp.QuadPart;//获得中止? dfMinus = (double)(QPart2-QPart1); dfTim = dfMinus / dfFreq;// 获得对应的时间|单位为秒 }while(dfTim<0.000001);</pre> 其定时误差一般不过0.5微秒Q精度与CPU{机器配|有兟?br> <p><a >CZ工程下蝲</a><br><br></p><img src ="http://www.shnenglu.com/xpzhou/aggbug/22426.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/xpzhou/" target="_blank">榕树?/a> 2007-04-20 21:03 <a href="http://www.shnenglu.com/xpzhou/archive/2007/04/20/22426.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STL实践指南http://www.shnenglu.com/xpzhou/archive/2007/04/20/22341.html榕树?/dc:creator>榕树?/author>Fri, 20 Apr 2007 00:18:00 GMThttp://www.shnenglu.com/xpzhou/archive/2007/04/20/22341.htmlhttp://www.shnenglu.com/xpzhou/comments/22341.htmlhttp://www.shnenglu.com/xpzhou/archive/2007/04/20/22341.html#Feedback0http://www.shnenglu.com/xpzhou/comments/commentRss/22341.htmlhttp://www.shnenglu.com/xpzhou/services/trackbacks/22341.html介绍
q是一指导您如何在Microsoft Visual Studio下学习STLq进行实늚文章。这文章从STL的基知识讲vQ@序渐q,逐步深入Q涉及到了STL~写代码的方法、STL代码的编译和调试、命名空_namespaceQ、STL中的ANSI / ISO字符丌Ӏ各U不同类型的容器QcontainerQ、模板(templateQ、游标(IteratorQ、算法(AlgorithmsQ、分配器QAllocatorQ、容器的嵌套{方面的问题Q作者在q篇文章中对读者提Z一些徏议,q指Z使用STL时应该注意的问题。这文章覆盖面q,视角全面。不仅仅适合初学者学习STLQ更是广大读者用STL~程的实跉|南?


q是一指导您如何在Microsoft Visual Studio下学习STLq进行实늚文章。这文章从STL的基知识讲vQ@序渐q,逐步深入Q涉及到了STL~写代码的方法、STL代码的编译和调试、命名空_namespaceQ、STL中的ANSI / ISO字符丌Ӏ各U不同类型的容器QcontainerQ、模板(templateQ、游标(IteratorQ、算法(AlgorithmsQ、分配器QAllocatorQ、容器的嵌套{方面的问题Q作者在q篇文章中对读者提Z一些徏议,q指Z使用STL时应该注意的问题。这文章覆盖面q,视角全面。不仅仅适合初学者学习STLQ更是广大读者用STL~程的实跉|南?br>
STL?br>
STL (标准模版库,Standard Template Library)是当今每个从事C++~程的h需要掌握的一不错的技术。我觉得每一个初学STL的h应该p一D|间来熟悉它,比如Q学习STL时会有急剧升降的学习曲U,q且有一些命名是不太Ҏ凭直觉就能够C的(也许是好记的名字已经被用光了Q,然而如果一旦你掌握了STLQ你׃会觉得头痛了。和MFC相比QSTL更加复杂和强大?br>STL有以下的一些优点:

可以方便Ҏ地实现搜索数据或Ҏ据排序等一pd的算法;

调试E序时更加安全和方便Q?br>
即是h们用STL在UNIXq_下写的代码你也可以很Ҏ地理解(因ؓSTL是跨q_的)?br>
背景知识

写这一部分是让一些初学计机的读者在富有挑战性的计算机科学领域有一个良好的开端,而不必费力地了解那无Ih的行话术语和沉L规则Q在q里仅仅把那些行话和规则当作STLer们用于自q创造品吧?br>
使用代码
本文使用的代码在STL实践中主要具有指导意义?br>
一些基概念的定?br>
模板QTemplateQ——类Q以及结构等各种数据cd和函敎ͼ的宏QmacroQ。有时叫做甜饼切割机Qcookie cutterQ,正规的名U应叫做范型QgenericQ——一个类的模板叫做范型类Qgeneric classQ,而一个函数的模板也自然而然地被叫做范型函数Qgeneric functionQ?br>STL——标准模板库Q一些聪明h写的一些模板,现在已成为每个h所使用的标准C++语言中的一部分?br>容器QContainerQ——可容纳一些数据的模板cRSTL中有vectorQsetQmapQmultimap和deque{容器?br>向量QVectorQ——基本数l模板,q是一个容器?br>游标QIteratorQ——这是一个奇特的东西Q它是一个指针,用来指向STL容器中的元素Q也可以指向其它的元素?br>
Hello WorldE序

我愿意在我的黄金旉在这里写下我的程序:一个hello worldE序。这个程序将一个字W串传送到一个字W向量中Q然后每ơ显C向量中的一个字W。向量就像是盛放变长数组的花园,大约所有STL容器中有一半是Z向量的,如果你掌握了q个E序Q你便差不多掌握了整个STL的一半了?br>

//E序Qvector演示一
//目的Q理解STL中的向量

// #include "stdafx.h" -如果你用预~译的头文g包含这个头文g
#include <vector>  // STL向量的头文g。这里没?.h"?br>#include <iostream>  // 包含cout对象的头文g?br>using namespace std;  //保证在程序中可以使用std命名I间中的成员?br>
char* szHW = "Hello World";  
//q是一个字W数l,?#8221;\0”l束?br>
int main(int argc, char* argv[])
{
  vector <char> vec;  //声明一个字W向量vector (STL中的数组)

  //为字W数l定义一个游标iterator?br>  vector <char>::iterator vi;

  //初始化字W向量,Ҏ个字W串q行循环Q?br>  //用来把数据填攑ֈ字符向量中,直到遇到”\0”时结束?br>  char* cptr = szHW;  // 一个指针指?#8220;Hello World”字符?br>  while (*cptr != '\0')
  {  vec.push_back(*cptr);  cptr++;  }
  // push_back函数数据放在向量的N?br>
  // 向量中的字W一个个地显C在控制?br>  for (vi=vec.begin(); vi!=vec.end(); vi++)  
  // q是STL循环的规范化的开始——通常?"!=" Q?而不?"<"
  // 因ؓ"<" 在一些容器中没有定义?
  // begin()q回向量起始元素的游标(iteratorQ,end()q回向量末尾元素的游标(iteratorQ?br>  {  cout << *vi;  }  // 使用q算W?“*” 数据从游标指针中提取出来?br>  cout << endl;  // 换行

  return 0;
}


push_back是将数据攑օvectorQ向量)或dequeQ双端队列)的标准函数。Insert是一个与之类似的函数Q然而它在所有容器中都可以用,但是用法更加复杂。end()实际上是取末֊一Q取容器中末前一个元素)Q以便让循环正确q行——它q回的指针指向最靠近数组界限的数据。就像普通@环中的数l,比如for (i=0; i<6; i++) {ar[i] = i;} ——ar[6]是不存在的,在@环中不会辑ֈq个元素Q所以在循环中不会出现问题?br>
STL的烦g一——初始化

STL令h烦恼的地Ҏ在它初始化的时候。STL中容器的初始化比C/C++数组初始化要ȝ的多。你只能一个元素一个元素地来,或者先初始化一个普通数l再通过转化填放到容器中。我认ؓZ通常可以q样做:


//E序Q初始化演示
//目的Qؓ了说明STL中的向量是怎样初始化的?br>
#include <cstring>  // <cstring>?lt;string.h>相同
#include <vector>
using namespace std;

int ar[10] = {  12, 45, 234, 64, 12, 35, 63, 23, 12, 55  };
char* str = "Hello World";

int main(int argc, char* argv[])
{
  vector <int> vec1(ar, ar+10);
  vector <char> vec2(str, str+strlen(str));
  return 0;
}



在编E中Q有很多U方法来完成同样的工作。另一U填充向量的Ҏ是用更加熟悉的方括号Q比如下面的E序Q?br>
//E序Qvector演示?br>//目的Q理解带有数l下标和ҎLSTL向量

#include <cstring>
#include <vector>
#include <iostream>
using namespace std;

char* szHW = "Hello World";
int main(int argc, char* argv[])
{
  vector <char> vec(strlen(sHW)); //为向量分配内存空?br>  int i, k = 0;
  char* cptr = szHW;
  while (*cptr != '\0')
  {  vec[k] = *cptr;  cptr++;  k++;  }
  for (i=0; i<vec.size(); i++)
  {  cout << vec[i];  }
  cout << endl;
  return 0;
}


q个例子更加清晰Q但是对游标QiteratorQ的操作了Qƈ且定义了额外的整形数作ؓ下标Q而且Q你必须清楚地在E序中说明ؓ向量分配多少内存I间?br>
命名I间QNamespaceQ?br>
与STL相关的概忉|命名I间QnamespaceQ。STL定义在std命名I间中。有3U方法声明用的命名I间Q?br>
1Q用using关键字用这个命名空_在文件的剙Q但在声明的头文件下面加入:
using namespace std;
q对单个工程来说是最单也是最好的ҎQ这个方法可以把你的代码限定在std命名I间中?br>
2Q用每一个模板前Ҏ一个要使用的对象进行声明(像原Ş化)Q?br>using std::cout;
using std::endl;
using std::flush;
using std::set;
using std::inserter;
管q样写有些冗长,但可以对记忆使用的函数比较有利,q且你可以容易地声明q用其他命名空间中的成员?br>
3Q在每一ơ用std命名I间中的模版Ӟ使用std域标识符。比如:
typedef std::vector VEC_STR;
q种Ҏ虽然写v来比较冗长,但是是在混合使用多个命名I间时的最好方法。一些STL的狂热者一直用这U方法,q且把不使用q种Ҏ的h视ؓ异类。一些h会通过q种Ҏ建立一些宏来简化问题?br>
除此之外Q你可以把using namespace std加入CQ何域中,比如可以加入到函数的头部或一个控制@环体中?br>
一些徏?br>
Z避免在调试模式(debug modeQ出现恼人的警告Q用下面的~译器命令:

#pragma warning(disable: 4786)

另一条需要注意的是,你必ȝ保在两个括号之间或括号和名字之间用空格隔开Q因为是Z避免?#8220;>>”UMq算W؜淆。比?br>vector <list<int>> veclis;
q样写会报错Q而这样写Q?br>vector <list <int> > veclis;
可以避免错误?br>
                                STL实践指南Q中Q?br>
STL实践指南  Practical Guide to STL
作者:Jeff Bogan
译Q周?br>

Q接上篇Q?br>
另一U容器——集合(setQ?br>
q是微Y帮助文档中对集合QsetQ的解释Q?#8220;描述了一个控制变长元素序列的对象Q注Qset中的key和value是Keycd的,而map中的key和value是一个pairl构中的两个分量Q的模板c,每一个元素包含了一个排序键Qsort keyQ和一个?value)。对q个序列可以q行查找、插入、删除序列中的Q意一个元素,而完成这些操作的旉同这个序列中元素个数的对数成比例关系Qƈ且当游标指向一个已删除的元素时Q删除操作无效?#8221;
而一个经q更正的和更加实际的定义应该是:一个集合(setQ是一个容器,它其中所包含的元素的值是唯一的。这在收集一个数据的具体值的时候是有用的。集合中的元素按一定的序排列Qƈ被作为集合中的实例。如果你需要一个键/值对QpairQ来存储数据Qmap是一个更好的选择。一个集合通过一个链表来l织Q在插入操作和删除操作上比向量(vectorQ快Q但查找或添加末元素时会有些慢?br>下面是一个例子:

//E序Qset演示
//目的Q理解STL中的集合QsetQ?br>
#include <string>
#include <set>
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
  set <string> strset;
  set <string>::iterator si;
  strset.insert("cantaloupes");
  strset.insert("apple");
  strset.insert("orange");
  strset.insert("banana");
  strset.insert("grapes");
  strset.insert("grapes");  
  for (si=strset.begin(); si!=strset.end(); si++)  
  {  cout << *si << " ";  }
  cout << endl;
  return 0;
}

// 输出Q?apple banana cantaloupes grapes orange
//注意Q输出的集合中的元素是按字母大小序排列的,而且每个值都不重复?br>

如果你感兴趣的话Q你可以输出@环用下面的代码替换:

copy(strset.begin(), strset.end(), ostream_iterator<string>(cout, " "));

.集合QsetQ虽然更强大Q但我个为它有些不清晰的地方而且更容易出错,如果你明白了q一点,你会知道用集合(setQ可以做什么?br>
所有的STL容器

容器QContainerQ的概念的出现早于模板(templateQ,它原本是一个计机U学领域中的一个重要概念,但在q里Q它的概念和STL混合在一起了。下面是在STL中出现的7U容器:

vectorQ向量)——STL中标准而安全的数组。只能在vector ?#8220;前面”增加数据?br>dequeQ双端队列double-ended queueQ——在功能上和vector怼Q但是可以在前后两端向其中添加数据?
listQ列表)——游标一ơ只可以Ud一步。如果你寚w表已l很熟悉Q那么STL中的list则是一个双向链表(每个节点有指向前驱和指向后的两个指针)?br>setQ集合)——包含了l过排序了的数据Q这些数据的?value)必须是唯一的?br>mapQ映)——经q排序了的二元组的集合,map中的每个元素都是׃个值组成,其中的keyQ键|一个map中的键值必L唯一的)是在排序或搜索时使用Q它的值可以在容器中重新获取;而另一个值是该元素关联的数倹{比如,除了可以ar[43] = "overripe"q样扑ֈ一个数据,mapq可以通过ar["banana"] = "overripe"q样的方法找C个数据。如果你惌得其中的元素信息Q通过输入元素的全名就可以L实现?br>multisetQ多重集Q——和集合QsetQ相|然而其中的g要求必须是唯一的(卛_以有重复Q?br>multimapQ多重映)——和映射QmapQ相|然而其中的键g要求必须是唯一的(卛_以有重复Q?br>注意Q如果你阅读微Y的帮助文档,你会遇到ҎU容器的效率的陈q。比如:log(n*n)的插入时间。除非你要处理大量的数据Q否则这些时间的影响是可以忽略的。如果你发现你的E序有明昄滞后感或者需要处理时间攸养Itime criticalQ的事情Q你可以M解更多有兛_U容器运行效率的话题?br>
怎样在一个map中用类Q?br>
Map是一个通过keyQ键Q来获得value(?的模板类?br>另一个问题是你希望在map中用自qc而不是已有的数据cdQ比如现在已l用q的int。徏立一?#8220;为模板准备的Qtemplate-readyQ?#8221;c,你必ȝ保在该类中包含一些成员函数和重蝲操作W。下面的一些成员是必须的:

~省的构造函敎ͼ通常为空Q?br>
拯构造函?br>
重蝲?#8221;=”q算W?br>
你应该重载尽可能多的q算W来满特定模板的需要,比如Q如果你惛_义一个类作ؓ map中的键(keyQ,你必重载相关的q算W。但在这里不寚w载运符做过多讨Z?br>
//E序Q映自定义的类?br>//目的Q说明在map中怎样使用自定义的cR?br>
#include <string>
#include <iostream>
#include <vector>
#include <map>
using namespace std;

class CStudent
{
public :
  int nStudentID;
  int nAge;
public :
  //~省构造函数——通常为空
  CStudent()  {  }
  // 完整的构造函?br>  CStudent(int nSID, int nA)  {  nStudentID=nSID; nAge=nA;  }
  //拯构造函?br>  CStudent(const CStudent& ob)  
    {  nStudentID=ob.nStudentID; nAge=ob.nAge;  }
  // 重蝲“=”
  void operator = (const CStudent& ob)  
    {  nStudentID=ob.nStudentID; nAge=ob.nAge;  }
};

int main(int argc, char* argv[])
{
  map <string, CStudent> mapStudent;

  mapStudent["Joe Lennon"] = CStudent(103547, 22);
  mapStudent["Phil McCartney"] = CStudent(100723, 22);
  mapStudent["Raoul Starr"] = CStudent(107350, 24);
  mapStudent["Gordon Hamilton"] = CStudent(102330, 22);

  // 通过姓名来访问CstudentcM的成?br>  cout << "The Student number for Joe Lennon is " <<
    (mapStudent["Joe Lennon"].nStudentID) << endl;

  return 0;
}



TYPEDEF

如果你喜Ƣ用typedef关键字,下面是个例子Q?br>typedef set <int> SET_INT;
typedef SET_INT::iterator SET_INT_ITER


~写代码的一个习惯就是用大写字母和下划U来命名数据cd?br>
ANSI / ISO字符?br>
ANSI/ISO字符串在STL容器中用得很普遍。这是标准的字符串类Qƈ得到了广泛地提倡,然而在~Z格式声明的情况下׃出问题。你必须使用“<<”和输入输出流QiostreamQ代码(如dec, width{)字W串串联h?br>可在必要的时候用c_str()来重新获得字W指针?br>        
                
                                STL实践指南Q下Q?br>STL实践指南  Practical Guide to STL
作者:Jeff Bogan
译Q周?br>

Q接中篇Q?br>
游标QIteratorQ?br>
我说q游标是指针Q但不仅仅是指针。游标和指针很像Q功能很像指针,但是实际上,游标是通过重蝲一元的”*”?#8221;->”来从容器中间接地q回一个倹{将q些值存储在容器中ƈ不是一个好LQ因为每当一个新值添加到容器中或者有一个g容器中删除,q些值就会失效。在某种E度上,游标可以看作是句柄(handleQ。通常情况下游标(iteratorQ的cd可以有所变化Q这样容器也会有几种不同方式的{变:
iterator——对于除了vector以外的其他Q何容器,你可以通过q种游标在一ơ操作中在容器中朝向前的方向C步。这意味着对于q种游标你只能?#8220;++”操作W。而不能?#8220;--”?#8220;+=”操作W。而对于vectorq一U容器,你可以?#8220;+=”?#8220;?#8221;?#8220;++”?#8220;-=”中的M一U操作符?#8220;<”?#8220;<=”?#8220;>”?#8220;>=”?#8220;==”?#8220;!=”{比较运符?br>reverse_iterator ——如果你想用向后的方向而不是向前的方向的游标来遍历除vector之外的容器中的元素,你可以用reverse_iterator 来反转遍历的方向Q你q可以用rbegin()来代替begin()Q用rend()代替end()Q而此时的“++”操作W会朝向后的方向遍历?
const_iterator ——一个向前方向的游标Q它q回一个常数倹{你可以使用q种cd的游标来指向一个只ȝ倹{?br>const_reverse_iterator ——一个朝反方向遍历的游标Q它q回一个常数倹{?br>
Set和Map中的排序

除了cd和值外Q模板含有其他的参数。你可以传递一个回调函敎ͼ通常所说的声明“predicate”——这是带有一个参数的函数q回一个布|。例如,如果你想自动建立一个集合,集合中的元素按升序排列,你可以用明的Ҏ建立一个setc:

set <int, greater<int> > set1

greater 是另一个模板函敎ͼ范型函数Q,当值放|在容器中后Q它用来些值排序。如果你x降序排列q些|你可以这样写Q?br>
set <int, less<int> > set1

在实现算法时Q将声明QpredicateQ作Z个参C递到一个STL模板cM时会遇到很多的其他情况,下面会对这些情况进行详l描q?br>
STL 的烦g二——错误信?br>
q些模板的命名需要对~译器进行扩充,所以当~译器因某种原因发生故障Ӟ它会列出一D很长的错误信息Qƈ且这些错误信息晦涩难懂。我觉得处理q样的难题没有什么好办法。但最好的Ҏ是去查找q仔l研I误信息指明代码段的尾端。还有一个烦恼就是:当你双击错误信息Ӟ它会错误指向模版库的内部代码,而这些代码就更难M。一般情况下Q纠错的最好方法是重新查一下你的代码,q行时忽略所有的警告信息?br>
法QAlgorithmsQ?br>
法是模板中使用的函数。这才真正开始体现STL的强大之处。你可以学习一些大多数模板容器中都会用到的一些算法函敎ͼq样你可以通过最便的方式q行排序、查找、交换等操作。STL中包含着一pd实现法的函数。比如:sort(vec.begin()+1, vec.end()-1)可以实现寚wW一个和最后一个元素的其他元素的排序操作?br>容器自n不能使用法Q但两个容器中的游标可以限定容器中用算法的元素。既然这P法不直接受到容器的限制Q而是通过采用游标Q算法才能够得到支持。此外,很多ơ你会遇C递一个已l准备好了的函数Q以前提到的声明QpredicateQ作为参敎ͼ你也可以传递以前的旧倹{?br>下面的例子演CZ怎样使用法Q?br>
//E序Q测试分数统?br>//目的Q通过对向量中保存的分数的操作说明怎样使用法

#include <algorithm>  //如果要用算法函敎ͼ你必要包含q个头文件?br>#include <numeric>  // 包含accumulateQ求和)函数的头文g
#include <vector>
#include <iostream>
using namespace std;

int testscore[] = {67, 56, 24, 78, 99, 87, 56};

//判断一个成l是否通过了考试
bool passed_test(int n)
{
  return (n >= 60);
}

// 判断一个成l是否不及格
bool failed_test(int n)
{
  return (n < 60);
}

int main(int argc, char* argv[])
{
  int total;
  // 初始化向量,使之能够装入testscore数组中的元素
  vector <int> vecTestScore(testscore,
     testscore + sizeof(testscore) / sizeof(int));
  vector <int>::iterator vi;

  // 排序q显C向量中的数?br>  sort(vecTestScore.begin(), vecTestScore.end());
  cout << "Sorted Test Scores:" << endl;
  for (vi=vecTestScore.begin(); vi != vecTestScore.end(); vi++)
  {  cout << *vi << ", ";  }
  cout << endl;

  // 昄l计信息

  // min_element q回一?_iterator_ cd的对象,该对象指向值最的那个元素?br>  //“*”q算W提取元素中的倹{?br>  vi = min_element(vecTestScore.begin(), vecTestScore.end());
  cout << "The lowest score was " << *vi << "." << endl;

  //与min_elementcMQmax_element是选出最大倹{?br>  vi = max_element(vecTestScore.begin(), vecTestScore.end());
  cout << "The highest score was " << *vi << "." << endl;

  // 使用声明函数Qpredicate functionQ指vecTestScore.begin()和vecTestScore.end()Q来定通过考试的h数?br>  cout << count_if(vecTestScore.begin(), vecTestScore.end(), passed_test) <<
    " out of " << vecTestScore.size() <<
    " students passed the test" << endl;

  // 定有多h考试挂了
  cout << count_if(vecTestScore.begin(),
    vecTestScore.end(), failed_test) <<
    " out of " << vecTestScore.size() <<
    " students failed the test" << endl;

  //计算成Wd
  total = accumulate(vecTestScore.begin(),
     vecTestScore.end(), 0);
  // 计算昄q_成W
  cout << "Average score was " <<
    (total / (int)(vecTestScore.size())) << endl;

  return 0;
}


AllocatorQ分配器Q?br>
Allocator用在模板的初始化阶段Q是为对象和数组q行分配内存I间和释攄间操作的模板cR它在各U情况下扮演着很神U的角色Q它兛_的是高层内存的优化,而且寚w盒测试来_使用Allocator是最好的选择。通常Q我们不需要明指明它Q因为它们通常是作Z用添加的~省的参数出现的。如果在专业的测试工作中出现了AllocatorQ你最好搞清楚它是什么?br>
Embed TemplatesQ嵌入式模版Q和Derive TemplatesQ基模板Q?br>
每当你用一个普通的cȝ时候,你也可以在其中用一个STLcR它是可以被嵌入的:

class CParam
{
  string name;
  string unit;
  vector <double> vecData;
};


或者将它作Z个基c:

class CParam : public vector <double>
{
  string name;
  string unit;
};


STL模版cM为基cL需要}慎。这需要你适应q种~程方式?br>
模版中的模版

为构Z个复杂的数据l构Q你可以一个模板植入另一个模板中Q即“模版嵌套”Q。一般最好的Ҏ是在E序前面使用typedef关键字来定义一个在另一个模板中使用的模版类型?br>
// E序Q在向量中嵌入向量的演示?br>//目的Q说明怎样使用嵌套的STL容器?br>
#include <iostream>
#include <vector>

using namespace std;

typedef vector <int> VEC_INT;

int inp[2][2] = {{1, 1}, {2, 0}};  
  // 要放入模板中?x2的正则数l?br>
int main(int argc, char* argv[])
{
  int i, j;
  vector <VEC_INT> vecvec;
  // 如果你想用一句话实现q样的嵌套,你可以这样写Q?br>  // vector <vector <int> > vecvec;
  
  // 数l填入向?br>  VEC_INT v0(inp[0], inp[0]+2);  
    // 传递两个指?br>    // 数l中的值拷贝到向量?br>  VEC_INT v1(inp[1], inp[1]+2);

  vecvec.push_back(v0);
  vecvec.push_back(v1);

  for (i=0; i<2; i++)
  {
    for (j=0; j<2; j++)
    {
      cout << vecvec[i][j] << "  ";
    }
    cout << endl;
  }
  return 0;
}

// 输出Q?br>// 1 1
// 2 0


虽然在初始化时很ȝQ一旦你数据填如向量中Q你实C一个变长的可扩充的二维数组Q大可扩充直到使用完内存)。根据实际需要,可以使用各种容器的嵌套组合?br>
ȝ

STL是有用的Q但是用过E中的困隑֒ȝ是再所隑օ的。就像中国h所说的Q?#8220;如果你掌握了它,便犹如虎ȝ?#8221;


׃CSDN的文章编辑器可能?<"?>"之间的部分作为html标签qo掉了Q现贴出正确?#8220;试分数l计”E序如下Q?

//E序Q测试分数统?
//目的Q通过对向量中保存的分数的操作说明怎样使用法

#include <algorithm> //如果要用算法函敎ͼ你必要包含q个头文件?
#include <numeric> // 包含accumulateQ求和)函数的头文g
#include <vector>
#include <iostream>
using namespace std;

int testscore[] = {67, 56, 24, 78, 99, 87, 56};

//判断一个成l是否通过了考试
bool passed_test(int n)
{
return (n >= 60);
}

// 判断一个成l是否不及格
bool failed_test(int n)
{
return (n < 60);
}

int main(int argc, char* argv[])
{
int total;
// 初始化向量,使之能够装入testscore数组中的元素
vector <int> vecTestScore(testscore,
testscore + sizeof(testscore) / sizeof(int));
vector <int>::iterator vi;

// 排序q显C向量中的数?
sort(vecTestScore.begin(), vecTestScore.end());
cout << "Sorted Test Scores:" << endl;
for (vi=vecTestScore.begin(); vi != vecTestScore.end(); vi++)
{ cout << *vi << ", "; }
cout << endl;

// 昄l计信息

// min_element q回一?_iterator_ cd的对象,该对象指向值最的那个元素?
//“*”q算W提取元素中的倹{?
vi = min_element(vecTestScore.begin(), vecTestScore.end());
cout << "The lowest score was " << *vi << "." << endl;

//与min_elementcMQmax_element是选出最大倹{?
vi = max_element(vecTestScore.begin(), vecTestScore.end());
cout << "The highest score was " << *vi << "." << endl;

// 使用声明函数Qpredicate functionQ指vecTestScore.begin()和vecTestScore.end()Q来定通过考试的h数?
cout << count_if(vecTestScore.begin(), vecTestScore.end(), passed_test) <<
" out of " << vecTestScore.size() <<
" students passed the test" << endl;

// 定有多h考试挂了
cout << count_if(vecTestScore.begin(),
vecTestScore.end(), failed_test) <<
" out of " << vecTestScore.size() <<
" students failed the test" << endl;

//计算成Wd
total = accumulate(vecTestScore.begin(),
vecTestScore.end(), 0);
// 计算昄q_成W
cout << "Average score was " <<
(total / (int)(vecTestScore.size())) << endl;

return 0;
}



]]>
使用VC6.0实现H口的Q意分?/title><link>http://www.shnenglu.com/xpzhou/archive/2007/04/18/22244.html</link><dc:creator>榕树?/dc:creator><author>榕树?/author><pubDate>Wed, 18 Apr 2007 13:06:00 GMT</pubDate><guid>http://www.shnenglu.com/xpzhou/archive/2007/04/18/22244.html</guid><wfw:comment>http://www.shnenglu.com/xpzhou/comments/22244.html</wfw:comment><comments>http://www.shnenglu.com/xpzhou/archive/2007/04/18/22244.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/xpzhou/comments/commentRss/22244.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/xpzhou/services/trackbacks/22244.html</trackback:ping><description><![CDATA[<p><strong>一、关于CSplitterWndc?/strong><br> 我们在用CuteFtp或者NetAnt{工L时候,一般都会被其复杂的界面所吸引Q在q些界面中窗口被分割q的区域Q真正做CH口的Q意分剌Ӏ?那么我们自己如何创徏cM的界面,也实现窗口的L的分割呢 Q在VC6.0中这需要用到CSplitterWndcRCSplitterWnd看上d是一U特D的框架H口Q每个窗口都被相同的或者不同的视图所填充。当H口被切分后用户可以使用鼠标Ud切分条来调整H口的相对尺寸。虽然VC6.0支持从AppWizard中创建分割窗口,但是自动加入的分割条L不能让我们满意,因此我们q是通过手工增加代码来熟悉这个类?<br> CSplitterWnd的构造函C要包括下面三个?<br><font color=#663333>BOOL Create(CWnd* pParentWnd,int nMaxRows,int nMaxCols,SIZE sizeMin,CCreateContext* pContext,DWORD dwStyle,UINT nID);</font> <br>    功能描述Q该函数用来创徏动态切分窗口?br>    参数含义QpParentWnd 切分H口的父框架H口?br>    nMaxRows,nMaxCols是创建的最大的列数和行数?<br>    sizeMin是窗格的现实大小?<br>    pContext 大多数情况下传给父窗口?<br>    nID是字H口的ID? <br>  <font color=#663333>BOOL CreateStatic(CWnd* pParentWnd,int nRows,int nCols,DWORD dwStyle,UINT nID) </font><br>  功能描述Q用来创建切分窗口?<br>  参数含义同上?<br><font color=#663333>BOOL CreateView (int row,int col,CruntimeClass* pViewClass,SIZE sizeinit,CcreateContext* pContext);</font> <br>  功能描述Qؓ静态切分的H口的网格填充视图。在视图于切分H口联系在一L时候必 d切分窗口创建好?<br>  参数含义Q同上?br>  从CSplitterWnd源程序可以看Z是使用动态创建Createq是使用静态创建CreateStaticQ在函数中都调用了一个保护函数CreateCommonQ从下面的CreateCommon函数中的关键代码可以看出创徏CSplitterWnd的实质是创徏了一pd的MDI子窗口?<br>    <font color=#663333>DWORD dwCreateStyle = dwStyle & ~(WS_HSCROLL|WS_VSCROLL);<br>    if (afxData.bWin4) <br>       dwCreateStyle &= ~WS_BORDER; // create with the same wnd-class as MDI-Frame (no erase bkgnd) <br>    if (!CreateEx(0, _afxWndMDIFrame, NULL, dwCreateStyle, 0, 0, 0, 0,pParentWnd->m_hWnd, (HMENU)nID, NULL)) <br>      return FALSE; // create invisible </font><br><br><strong>二、创建嵌套分割窗?/strong> <br><strong>  2.1创徏动态分割窗?/strong><br>  动态分割窗口用CreateҎ。下面的代码创?x2的窗根{?<br>  <font color=#663333>m_wndSplitter.Create(this,2,2,CSize(100,100),pContext);</font> <br>  但是动态创建的分割H口的窗格数目不能超q?x2Q而且对于所有的H格Q都必须׃n同一个视图,所受的限制也比较多Q因此我们不动态创Z为重炏V我们的主要_֊攑֜静态分割窗口的创徏上?<br>  <strong>2.2创徏静态分割窗?/strong><br>与动态创建相比,静态创建的代码要简单许多,而且可以最多创?6x16的窗根{不同的H格我们可以使用CreateView填充不同的视图?<br>在这里我们将创徏CuteFtp的窗口分剌ӀCuteFtp的分割情况如下:</p> <div align=center> <table height=223 cellSpacing=1 cellPadding=0 width=446 bgColor=#666666 border=0> <tbody> <tr bgColor=#eeeeee> <td colSpan=2 height=46> <div align=center><font face="Arial, Helvetica, sans-serif" size=2>CCuteFTPView</font></div> </td> </tr> <tr bgColor=#eeeeee> <td height=123> <div align=center><font face="Arial, Helvetica, sans-serif" size=2>CView2</font></div> </td> <td height=123> <div align=center><font face="Arial, Helvetica, sans-serif" size=2>CView3</font></div> </td> </tr> <tr bgColor=#eeeeee> <td colSpan=2 height=44> <div align=center><font face="Arial, Helvetica, sans-serif" size=2>CView4</font></div> </td> </tr> </tbody> </table> </div> <p>  创徏步骤Q?<br>  ?在创Z前我们必d用AppWizard生成单文档CuteFTPQ生成的视类?CCuteFTPView.同时在增加三个视cL者从视类l承而来的派生类CView2,CView3 CView4. <br>  ?<strong>增加成员Q?/strong> <br>  在Cmainfrm.h中我们将增加下面的代码: <br>  <font color=#663333>CSplitterWnd wndSplitter1;<br>  CSplitterWnd wndSplitter2;</font><br>  ?<strong>重蝲CMainFrame::OnCreateClient()函数Q?/strong><br>  <font color=#663333>BOOL CMainFrame::OnCreateClient( LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext) <br>  { //创徏一个静态分栏窗口,分ؓ三行一?<br>    if(m_wndSplitter1.CreateStatic(this,3,1)==NULL) <br>      return FALSE;<br>    //CCuteFTPViewq接??列窗g<br>    m_wndSplitter1.CreateView(0,0,RUNTIME_CLASS(CCuteFTPView),CSize(100,100), pContext); <br>    m_wndSplitter1.CreateView(2,0,RUNTIME_CLASS(CView4),CSize(100,100),pContext); //CView4q接???br>    if(m_wndSplitter2.CreateStatic(&m_wndSplitter,1,2,WS_CHILD|WS_VISIBLE, m_wndSplitter.IdFromRowCol(1, 0))==NULL) <br>      return FALSE; //第1?列再分开1??<br>    //CView2c连接到W二个分栏对象的0??br>    m_wndSplitter2.CreateView(0,0,RUNTIME_CLASS(CView2),CSize(400,300),pContext); //CView3c连接到W二个分栏对象的0??br>    m_wndSplitter2.CreateView(0,1,RUNTIME_CLASS(CView3),CSize(400,300),pContext); <br>    return TRUE; <br>  } </font><br><strong>2.3实现各个分割区域的通信</strong> <br>?strong>有文档相q的视图之间的通信<br></strong>由AppWizard生成的CCuteFTPView是与文档相连的,同时我们也让CView2与文档相q,因此我们需要修改CCuteFTPApp的InitInstance()函数Q我们将增加下面的部分?br><font color=#663333>AddDocTemplate (new CMultiDocTemplate(IDR_VIEW2TYPE, <br>RUNTIME_CLASS(CMainDoc), <br>RUNTIME_CLASS(CMDIChildWnd), <br>RUNTIME_CLASS(CView2))); </font><br>我们现在来实现CCuteFTPView与CView2之间的通信。由于跟文档cȝq的视图c?是不能安全的与除文档cM外的其余的视囄通信的。因此我们只能让他们都与文档 c通信。在文档中我们设|相应的指针以用来获的各个视图。我们重?CCuteFTPView::OnOpenDocument()函数Q?<br><font color=#663333>CCuteFTPView* pCuteFTPView;<br>CView2* pView2;<br>POSITION pos;<br>CView* pView;<br>while(pos!=NULL)<br>{<br>  pView=GetNextView(pos); <br>  if(pView->IsKindOf(RUNTIME_CLASS(CCuteFTPView))==NULL) <br>    pCuteFTPView=(CCuteFTPView*)pView; <br>  else(pView->IsKindOf(RUNTIME_CLASS(CCuteFTPView))==NULL) <br>    pView2=(CView2*)pView; <br>} </font><br>q样我们在文档类中就L了跟它相q的所有的视图的指针?br>如果需要在 CCuteFTPView中调用CView2中的一个方法DoIt()则代码如下: <br><font color=#663333>CCuteFTPDoc* pDoc=GetDocument();<br>CView2* pView2=pDoc->pView3;<br>pView3.DoIt(); </font><br>?strong>无文档视图与文档兌视图之间的通信<br></strong>CView3和CView4都是不与文档相关联的。我们现在实现CView3与CView2的通信.正如前面所_CView2只能安全的与CCuteFTPDoc通信Q因此,CView3如果需要跟CView2通信Q也必须借助于文档类。因此程序的关键是如何在CView3中获得文档的指针。视囄中没有这LcL员可以用来直接访问文档类。但是我们知道在ȝ口类MainFrame中我们可以获得程序的LH口cȝ指针。因此我们只要获得程序主H口了的指针Q就可以解决问题了。代码实现在CView3中访问CView2中的DoIt()Ҏ?br><br>CView3中的代码如下Q?<br><br><font color=#663333>CMainFrame* MainFrame=(CMainFrame*)this->GetParent()->GetParent(); <br>CCuteFTPDoc* Doc=(CCuteFTPDoc*)MainFrame->GetActiveDocument();<br>if(Doc!=NULL) Doc->DoIt(); <br><br>CCuteFTPDoc中的相应的处理函数DoIt()代码如下Q?<br><br>CView2* pView2; <br>POSITION pos; <br>CView* pView; <br>while(pos!=NULL) <br>{ <br>  pView=GetNextView(pos);<br>  if(pView->IsKindOf(RUNTIME_CLASS(CView2))==NULL) <br>  pView2=(CView2*)pView; <br>} <br>pView2->DoIt(); </font><br>?strong>无文档关联视图之间的通信<br></strong>CView3和CView4都是不跟文档相连的,如何实现他们之间的通信呢?正如我们在上面所说的那样Q由于在L架中我们可以讉KL的视图,因此我们的主要Q 务还是在E序中获得主框架的指针。在CView3中访问CView4中的ҎDoIt()?<br><font color=#663333>CMainFrame* MainFrame=(CMainFrame*)this->GetParent()->GetParent(); <br>CView4* View4=(CView4*)MainFrame->m_wndSplitter1.GetPane(2,0); <br>View4->DoIt(); </font><br><br>到现在我们已l实CCuteFTP的主H口的框架ƈ且能够实C们之间相互通信的框架?同样的我们可以实现其他的一些流行界面例如NetAntsQFoxmail的分剌Ӏ?<br><br><strong>三、关于对话框的分?/strong> <br>到目前ؓ止,只有Z文档/视图的程序才能用CSplitterWndQ而基于对话框的应用程序却不支持CSplitterWnd,但是如果我们在承类中重载一些虚拟方法,也能使CSplitterWnd 在对话框E序中用。从MFC的源E序WinSplit.cpp中可以看出,Z获得父窗口的地方E序都调用了虚拟ҎGetParentFrame(),因此如果在对话框中用,我们必须它改ؓGetParent();因此我们CSplitterWnd的下面几个方法重载?br>  <font color=#663333>virtual void StartTracking(int ht); <br>  virtual CWnd* GetActivePane(int* pRow = NULL, int* pCol = NULL); <br>  virtual void SetActivePane( int row, int col, CWnd* pWnd = NULL ); <br>  virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); <br>  virtual BOOL OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult ); <br>  virtual BOOL OnWndMsg( UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult ); </font><br>具体实现如下Q实C我将l出原有代码的主要部分以及修改后的代码以作对比?br>在cpp文g中加入下面的枚Dcd?<br><font color=#663333>enum HitTestValue <br>{ <br>  noHit = 0,//表示没有选中M对象<br>  vSplitterBox = 1,<br>  hSplitterBox = 2,<br>  bothSplitterBox = 3,<br>  vSplitterBar1 = 101,//代表各个方向的水q_割条<br>  vSplitterBar15 = 115,<br>  hSplitterBar1 = 201,//代表垂直方向的各个分割条<br>  hSplitterBar15 = 215,<br>  splitterIntersection1 = 301,//代表各个交叉?br>  splitterIntersection225 = 525<br>};<br><br>CWnd* CxSplitterWnd::GetActivePane(int* pRow, int* pCol)<br>{<br>  ASSERT_VALID(this); <br>  //获得当前的获得焦点的H口<br>  //下面注释_体的是原有的代码的主要部分?br>  // CWnd* pView = NULL;<br>  //CFrameWnd* pFrameWnd = GetParentFrame();<br>  //ASSERT_VALID(pFrameWnd);<br>  //pView = pFrameWnd->GetActiveView();<br>  //if (pView == NULL)<br>  // pView = GetFocus();<br>  CWnd* pView = GetFocus();<br>  if (pView != NULL && !IsChildPane(pView, pRow, pCol))<br>    pView = NULL;<br>  return pView; <br>} <br><br>void CxSplitterWnd::SetActivePane( int row, int col, CWnd* pWnd) <br>{<br>  CWnd* pPane = pWnd == NULL ? GetPane(row, col) : pWnd; <br>  //下面加注释粗体的是原有代码的主要部分?br>  //FrameWnd* pFrameWnd = GetParentFrame();<br>  //ASSERT_VALID(pFrameWnd); <br>  //pFrameWnd->SetActiveView((CView*)pPane); <br>  pPane->SetFocus();//修改后的语句 <br>}<br><br>void CxSplitterWnd::StartTracking(int ht)<br>{<br>  ASSERT_VALID(this); <br>  if (ht == noHit) <br>    return;<br>  // GetHitRect will restrict 'm_rectLimit' as appropriate <br>  GetInsideRect(m_rectLimit);<br>  if (ht >= splitterIntersection1 && ht <= splitterIntersection225) <br>  { <br>    // split two directions (two tracking rectangles) <br>    int row = (ht - splitterIntersection1) / 15; <br>    int col = (ht - splitterIntersection1) % 15; <br>    GetHitRect(row + vSplitterBar1, m_rectTracker); <br>    int yTrackOffset = m_ptTrackOffset.y; <br>    m_bTracking2 = TRUE; <br>    GetHitRect(col + hSplitterBar1, m_rectTracker2); <br>    m_ptTrackOffset.y = yTrackOffset; <br>  } <br>  else if (ht == bothSplitterBox) <br>  { <br>  // hit on splitter boxes (for keyboard) <br>  GetHitRect(vSplitterBox, m_rectTracker); <br>  int yTrackOffset = m_ptTrackOffset.y; <br>  m_bTracking2 = TRUE; <br>  GetHitRect(hSplitterBox, m_rectTracker2); <br>  m_ptTrackOffset.y = yTrackOffset; // center it <br>  m_rectTracker.OffsetRect(0, m_rectLimit.Height()/2); m_rectTracker2.OffsetRect(m_rectLimit.Width()/2, 0); <br>  } <br>  else<br>  { <br>  // only hit one bar <br>  GetHitRect(ht, m_rectTracker); <br>  } <br><br>//下面加注释的从E序中删厅R?<br>//CView* pView = (CView*)GetActivePane(); <br>//if (pView != NULL && pView->IsKindOf(RUNTIME_CLASS(CView))) <br>//{ <br>// ASSERT_VALID(pView); <br>// CFrameWnd* pFrameWnd = GetParentFrame(); <br>//ASSERT_VALID(pFrameWnd); <br>//pView->OnActivateFrame(WA_INACTIVE, pFrameWnd); <br>// } <br>// steal focus and capture<br>  SetCapture();<br>  SetFocus();<br>  // make sure no updates are pending <br>  RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW); <br>  // set tracking state and appropriate cursor<br>  m_bTracking = TRUE;<br>  OnInvertTracker(m_rectTracker); <br>  if (m_bTracking2) <br>    OnInvertTracker(m_rectTracker2); <br>  m_htTrack = ht; <br>  SetSplitCursor(ht); <br>  }<br><br>BOOL CxSplitterWnd::OnCommand(WPARAM wParam, LPARAM lParam) <br>{ <br>  if (CWnd::OnCommand(wParam, lParam)) <br>    return TRUE; <br>  //下面_体的是原程序的语句 <br>//<strong>return GetParentFrame()->SendMessage(WM_COMMAND, wParam, lParam); </strong><br>  return GetParent()->SendMessage(WM_COMMAND, wParam, lParam); <br>}<br>BOOL CxSplitterWnd::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult )<br>{<br>  if (CWnd::OnNotify(wParam, lParam, pResult)) <br>    return TRUE; <br>  //下面_体的是源程序的语句<br>  //<strong>*pResult = GetParentFrame()->SendMessage(WM_NOTIFY, wParam, lParam);</strong><br>  *pResult = GetParent()->SendMessage(WM_NOTIFY, wParam, lParam);<br>  return TRUE;<br>} <br><br>BOOL CxSplitterWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult) <br>{ <br>  // The code line below is necessary if using CxSplitterWnd in a regular dll <br>  // AFX_MANAGE_STATE(AfxGetStaticModuleState());<br>  return CWnd::OnWndMsg(message, wParam, lParam, pResult); <br>} </font><br>q样我们可以在对话框中使用CxSplitterWndcM?<br><br><strong>四、CSplitterWnd的扩?/strong> <br>CSplitterWnd扩展话题是很多的Q我们可以通过对原有方法的覆盖或者增加新的方法来扩展CSplitterWnd。我们在此仅举两个方面的例子?<br><strong>4.1锁定切分?/strong><br>当用户创建好分割H口后,有时q不希望通过拖动切分条来调节H口的大。这时就必须锁定切分条。锁定切分条的最单的Ҏ莫过于不让CSplitterWnd来处理WM_LBUTTONDOWN,WM_MOUSEMOVE,WM_SETCURSOR消息Q而是这些消息交lCWndH口q行处理Q从而屏蔽掉q些消息。拿WM_LBUTTONDOWN处理q程来说。修改ؓ如下Q?<br><font color=#663333>void CXXSplitterWnd::OnLButtonDown(UINT nFlags,CPoint point) <br>{ <br>  CWnd::OnLButtonDown(nFlags,point);<br>} </font><br>其余的处理方法类伹{?<br><strong>4.2切分条的定制</strong> <br>由Window自己生成的切分条L固定的,没有M的变化,我们在用一些Y件比如ACDSee的时候却能发现它们的切分条却是和自动生成的切分条不一L。那么如何定制自q切分条呢Q通过重蝲CSplitterWnd的虚ҎOnDrawSplitter和OnInvertTracker可以辑ֈq样的目的。下面的代码生成的效果是分割H口的边界颜色ؓU色Q分割条的颜色ؓl色.代码如下Q?br><font color=#663333>void CSplitterWndEx::OnDrawSplitter(CDC *pDC, ESplitType nType, const CRect &rectArg)<br>{<br>  if(pDC==NULL) <br>  { <br>  RedrawWindow(rectArg,NULL,RDW_INVALIDATE|RDW_NOCHILDREN);<br>  return;<br>  } <br>  ASSERT_VALID(pDC);<br>  CRect rc=rectArg;<br>  switch(nType) <br>  { <br>  case splitBorder:<br>  //重画分割H口边界,使之为红?<br>    pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0));<br>    rc.InflateRect(-CX_BORDER,-CY_BORDER); <br>    pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0)); <br>    return; <br>  case splitBox:<br>    pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0));<br>    rc.InflateRect(-CX_BORDER,-CY_BORDER); <br>    pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0));<br>    rc.InflateRect(-CX_BORDER,-CY_BORDER);<br>    pDC->FillSolidRect(rc,RGB(0,0,0)); <br>    pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0));<br>    return; <br>  case splitBar: <br>  //重画分割条,使之为绿?<br>    pDC->FillSolidRect(rc,RGB(255,255,255));<br>    rc.InflateRect(-5,-5); <br>    pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0)); <br>    return; <br>  default: <br>    ASSERT(FALSE); <br>  } <br>  pDC->FillSolidRect(rc,RGB(0,0,255));<br>} <br>void CSplitterWndEx::OnInvertTracker(CRect &rect) <br>{ <br>  ASSERT_VALID(this);<br>  ASSERT(!rect.IsRectEmpty()); <br>  ASSERT((GetStyle()&WS_CLIPCHILDREN)==0);<br>  CRect rc=rect; <br>  rc.InflateRect(2,2);<br>  CDC* pDC=GetDC(); <br>  CBrush* pBrush=CDC::GetHalftoneBrush();<br>  HBRUSH hOldBrush=NULL;<br>  if(pBrush!=NULL) hOldBrush=(HBRUSH)SelectObject(pDC->m_hDC,pBrush->m_hObject);<br>  pDC->PatBlt(rc.left,rc.top,rc.Width(),rc.Height(),BLACKNESS); <br>  if(hOldBrush!=NULL) <br>  SelectObject(pDC->m_hDC,hOldBrush);<br>  ReleaseDC(pDC); <br>} </font><br>同样我们只要l承CSplitterWnd中的其余的一些虚拟方法就可以生成h自己个性的分割H口了?br></p> <img src ="http://www.shnenglu.com/xpzhou/aggbug/22244.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/xpzhou/" target="_blank">榕树?/a> 2007-04-18 21:06 <a href="http://www.shnenglu.com/xpzhou/archive/2007/04/18/22244.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pragma指o?/title><link>http://www.shnenglu.com/xpzhou/archive/2007/04/18/22193.html</link><dc:creator>榕树?/dc:creator><author>榕树?/author><pubDate>Wed, 18 Apr 2007 02:24:00 GMT</pubDate><guid>http://www.shnenglu.com/xpzhou/archive/2007/04/18/22193.html</guid><wfw:comment>http://www.shnenglu.com/xpzhou/comments/22193.html</wfw:comment><comments>http://www.shnenglu.com/xpzhou/archive/2007/04/18/22193.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/xpzhou/comments/commentRss/22193.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/xpzhou/services/trackbacks/22193.html</trackback:ping><description><![CDATA[在编写程序的时?我们l常要用?pragma指o来设定编译器的状态或者是指示~译器完成一些特定的动作.<br> 下面介绍了一下该指o的一些常用参?希望对大家有所帮助! <p> 一. message 参数?br> message<br> 它能够在~译信息输出H口中输出相应的信息Q这对于源代码信息的控制是非帔R要的?/p> <p> 其用方法ؓQ?nbsp; #pragma message("消息文本")</p> <p> 当编译器遇到q条指o时就在编译输出窗口中消息文本打印出来?br> 当我们在E序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设|这些宏Q此时我们可以用q条指o在编译的时候就q行查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86q个宏可以用下面的方法:<br>#ifdef _X86<br>#pragma message("_X86 macro activated!")<br>#endif<br> 当我们定义了_X86q个宏以后,应用E序在编译时׃在编译输出窗口里昄<br> "_X86 macro activated!"<br> q样Q我们就不会因ؓ不记得自己定义的一些特定的宏而抓x腮了?/p> <p> ? 另一个用得比较多的#pragma参数是code_seg?br> 格式如:<br> #pragma code_seg( [ [ { push | pop}, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] )<br> 该指令用来指定函数在.obj文g中存攄?观察OBJ文g可以使用VC自带的dumpbin命o行程?函数?obj文g中默认的存放节ؓ.text节,如果code_seg没有带参数的?则函数存攑֜.text节中?/p> <p> push (可选参? 一个记录放到内部编译器的堆栈中,可选参数可以ؓ一个标识符或者节?br> pop(可选参? 一个记录从堆栈端弹出,该记录可以ؓ一个标识符或者节?br> identifier (可选参? 当用push指o?为压入堆栈的记录指派的一个标识符,当该标识W被删除的时候和其相关的堆栈中的记录被弹出堆栈<br>   "segment-name" (可选参? 表示函数存放的节?br> 例如:<br> //默认情况?函数被存攑֜.text节中<br> void func1() {   // stored in .text<br> }</p> <p> //函数存攑֜.my_data1节中<br> #pragma code_seg(".my_data1")<br> void func2() {   // stored in my_data1<br> }</p> <p> //r1为标识符,函数放?my_data2节中<br> #pragma code_seg(push, r1, ".my_data2")<br> void func3() {   // stored in my_data2<br> }</p> <p> int main() {<br> }</p> <p> ? #pragma once (比较常用Q?br> q是一个比较常用的指o,只要在头文g的最开始加入这条指令就能够保证头文件被~译一?/p> <p> ? #pragma hdrstop表示预编译头文g到此为止Q后面的头文件不q行预编译?br> BCB可以预编译头文g以加快链接的速度Q但如果所有头文g都进行预~译又可能占太多盘I间Q所以用这个选项排除一些头文g?br> 有时单元之间有依赖关p,比如单元A依赖单元BQ所以单元B要先于单元A~译。你可以?pragma startup指定~译优先U,如果使用?pragma package(smart_init) QBCB׃Ҏ优先U的大小先后~译?/p> <p> ? #pragma warning指o<br> 该指令允许有选择性的修改~译器的警告消息的行?br> 指o格式如下:<br> #pragma warning( warning-specifier : warning-number-list [; warning-specifier : warning-number-list...]<br> #pragma warning( push[ ,n ] )<br> #pragma warning( pop )</p> <p> 主要用到的警告表C有如下几个:</p> <p> once:只显CZ?警告/错误{?消息<br> default:重置~译器的警告行ؓ到默认状?br> 1,2,3,4:四个警告U别<br> disable:止指定的警告信?br> error:指定的警告信息作ؓ错误报告</p> <p> 如果大家对上面的解释不是很理?可以参考一下下面的例子及说?/p> <p> #pragma warning( disable : 4507 34; once : 4385; error : 164 )<br> {h于:<br> #pragma warning(disable:4507 34)  // 不显C?507?4可告信?br> #pragma warning(once:4385)   // 4385可告信息仅报告一?br> #pragma warning(error:164)   // ?64可告信息作Z个错误?br> 同时q个pragma warning 也支持如下格式:<br> #pragma warning( push [ ,n ] )<br> #pragma warning( pop )<br> q里n代表一个警告等U?1---4)?br> #pragma warning( push )保存所有警告信息的现有的警告状态?br> #pragma warning( push, n)保存所有警告信息的现有的警告状态,q且把全局警告{讑֮为n?br> #pragma warning( pop )向栈中弹出最后一个警告信息,在入栈和出栈之间所作的一切改动取消。例如:<br> #pragma warning( push )<br> #pragma warning( disable : 4705 )<br> #pragma warning( disable : 4706 )<br> #pragma warning( disable : 4707 )<br> #pragma warning( pop )</p> <p> 在这D代码的最后,重新保存所有的警告信息(包括4705Q?706?707)</p> <p> 在用标准C++q行~程的时候经怼得到很多的警告信?而这些警告信息都是不必要的提C?所以我们可以?pragma warning(disable:4786)来禁止该cd的警告在vc中用ADO的时候也会得C必要的警告信?q个时候我们可以通过#pragma warning(disable:4146)来消除该cd的警告信?/p> <p> ? pragma comment(...)<br> 该指令的格式为:  #pragma comment( "comment-type" [, commentstring] )<br> 该指令将一个注释记录放入一个对象文件或可执行文件中,comment-type(注释cd):可以指定ZU预定义的标识符的其中一U?br> 五种预定义的标识Wؓ:</p> <p> 1、compiler:编译器的版本号和名U放入目标文件中,本条注释记录被~译器忽?br>如果你ؓ该记录类型提供了commentstring参数,~译器将会生一个警?br>例如:#pragma comment( compiler )</p> <p> 2、exestr:commentstring参数攑օ目标文g?在链接的时候这个字W串被攑օ到可执行文g?当操作系l加载可执行文g的时?该参数字W串不会被加载到内存?但是,该字W串可以被dumpbin之类的程序查扑ևq打印出?你可以用q个标识W将版本L之类的信息嵌入到可执行文件中!</p> <p> 3、lib:q是一个非常常用的关键?用来一个库文g链接到目标文件中常用的lib关键字,可以帮我们连入一个库文g?br> 例如: <br> #pragma comment(lib, "user32.lib")<br> 该指令用来将user32.lib库文件加入到本工E中</p> <p> 4、linker:一个链接选项攑օ目标文g?你可以用这个指令来代替由命令行传入的或者在开发环境中讄的链接选项,你可以指?include选项来强制包含某个对?例如:<br>#pragma comment(linker, "/include:__mySymbol")<br>你可以在E序中设|下列链接选项<br>/DEFAULTLIB<br>/EXPORT<br>/INCLUDE<br>/MERGE<br>/SECTION</p> <p> q些选项在这里就不一一说明?详细信息Lmsdn!</p> <p> 5、user:一般的注释信息攑օ目标文g中commentstring参数包含注释的文本信?q个注释记录被链接器忽?br> 例如:<br> #pragma comment( user, "Compiled on " __DATE__ " at " __TIME__ ) </p> <img src ="http://www.shnenglu.com/xpzhou/aggbug/22193.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/xpzhou/" target="_blank">榕树?/a> 2007-04-18 10:24 <a href="http://www.shnenglu.com/xpzhou/archive/2007/04/18/22193.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.qhsy217.cn" target="_blank">þþƷ޸</a>| <a href="http://www.commonsoft.cn" target="_blank">Ʒһþþ </a>| <a href="http://www.yc-shop.cn" target="_blank">þþƷĻ23ҳ</a>| <a href="http://www.68360.cn" target="_blank">þþþ޾Ʒþþþþþ</a>| <a href="http://www.hxg123.cn" target="_blank">˾þþƷavһ</a>| <a href="http://www.tongdiaocj.cn" target="_blank">þùƷþþƷ</a>| <a href="http://www.showfans.com.cn" target="_blank">þۺϳDž</a>| <a href="http://www.pophyh.cn" target="_blank">þþžžþƷֱ</a>| <a href="http://www.xsdbw.cn" target="_blank">þþþAVվ </a>| <a href="http://www.btalhb.cn" target="_blank">þ99Ʒþþ</a>| <a href="http://www.haokan1.cn" target="_blank">ھƷþþþþþ</a>| <a href="http://www.52wysq.cn" target="_blank">91ɫۺϾþ</a>| <a href="http://www.hahaowen.cn" target="_blank">þþƷav鶹ɫ</a>| <a href="http://www.jkwovf.cn" target="_blank">ھƷþù</a>| <a href="http://www.zhijin168.com.cn" target="_blank">ɫ99þþþø߳ۺӰԺ </a>| <a href="http://www.88crm.cn" target="_blank">ŮƷþþ2020</a>| <a href="http://www.o7xcp.cn" target="_blank">ҹþþƷ</a>| <a href="http://www.forexpo.cn" target="_blank">þŷձƷ</a>| <a href="http://www.box6.cn" target="_blank">þþþŷղAV </a>| <a href="http://www.710p.cn" target="_blank">88þþƷһëƬ </a>| <a href="http://www.fangfangmm.cn" target="_blank">ƷþþĻһ</a>| <a href="http://www.jijijian.cn" target="_blank">þ99Ʒ鶹</a>| <a href="http://www.guer.org.cn" target="_blank">ĻƷþþþ</a>| <a href="http://www.soba30.cn" target="_blank">þþþþ޾ƷӰԺ</a>| <a href="http://www.ruea.cn" target="_blank">޵һAVվþþƷ˵AV </a>| <a href="http://www.sh-jixiang.cn" target="_blank">þseƷһӰԺ</a>| <a href="http://www.sjpeixun.cn" target="_blank">99þþƷ鶹</a>| <a href="http://www.qkqkkq.cn" target="_blank">뾫ƷþþӰ</a>| <a href="http://www.yichengsh.com.cn" target="_blank">þøƬ</a>| <a href="http://www.honglinzhiyi.cn" target="_blank">Ʒ99þþþ</a>| <a href="http://www.paysearch.cn" target="_blank">þWWW˳ɡƬ</a>| <a href="http://www.1985328.cn" target="_blank">þ㽶ۺɫһۺɫ88</a>| <a href="http://www.tangwoshi.cn" target="_blank">þþѾƷre6</a>| <a href="http://www.szdeyi.cn" target="_blank">þþŮ붯ȺëƬ </a>| <a href="http://www.nba52.cn" target="_blank">þó18վ</a>| <a href="http://www.zgyjys.cn" target="_blank">þ</a>| <a href="http://www.ktze6z.cn" target="_blank">þùѹۿƷ</a>| <a href="http://www.sobseo.cn" target="_blank">þþƷ</a>| <a href="http://www.huiju58.cn" target="_blank">˾ھƷþþþ</a>| <a href="http://www.caipusheji2016.cn" target="_blank">avԾþþþa鶹</a>| <a href="http://www.laoji2004.cn" target="_blank">þӰԺҹƬ </a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>