﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客--文章分类-vc++6.0</title><link>http://www.cppblog.com/guanchanghui/category/2633.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 27 May 2008 16:15:28 GMT</lastBuildDate><pubDate>Tue, 27 May 2008 16:15:28 GMT</pubDate><ttl>60</ttl><item><title>winsock1.1 and winsock2.0 的使用方法</title><link>http://www.cppblog.com/guanchanghui/articles/12785.html</link><dc:creator>asdfastone</dc:creator><author>asdfastone</author><pubDate>Thu, 21 Sep 2006 03:14:00 GMT</pubDate><guid>http://www.cppblog.com/guanchanghui/articles/12785.html</guid><description><![CDATA[
		<p>
				<font face="Verdana" size="2">1.在网络通信中，由于网络拥挤或一次发送的数据量过大等原因，经常会发生交换的数据在短时间内不能传送完，收发数据的函数因此不能返回的现象，这种现象叫作阻塞。winsock对有可能阻塞的函数提供了两种处理方式--阻塞和非阻塞。在阻塞方式下，收发数据的函数在被调用后一直要到传送完毕或者出错才返回：在阻塞期间，除了等待网络操作的完成不能进行任何操作。对于非阻塞方式，函数被调用后立即返回；当网络操作传送完成后，有winsock给应用程序发送一个消息，通知操作完成，此时可以根据发送的消息传出的参数判断操作是否正常。</font>
				<br />
				<font face="Verdana" size="2">2.在编程时，应尽量使用非阻塞方式。因为在阻塞方式下，用户可能会因为长时间的等待而失去耐心继而关闭应用程序的主窗口，这样当网络操作的函数从winsock的动态链接库中返回时，主程序已经从内存中删除，可能会造成内存的异常。虽然现在的操作系统已经可以从系统级正确地处理这种内存问题，但还是建议读者关注这种情况的的发生。<br />3.windows Socket2与Windows Socket1.1两个版本向后兼容：源码和二进制代码。程序员要做的只是包含新的头文件winsock2.h和简单得ws2_32.lib地链接。具体如下：<br />winsock1.1:</font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008080">1</span>
				<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">winsock.h</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #008080">2</span>
				<span style="COLOR: #000000">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#pragma comment(lib,</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">wsock32.lib</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">)<br /></span>
				<span style="COLOR: #008080">3</span>
				<span style="COLOR: #000000">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />或者<br /></span>
				<span style="COLOR: #008080">4</span>
				<span style="COLOR: #000000">
						<img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />alt</span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">f7 link</span>
				<span style="COLOR: #000000">-&gt;</span>
				<span style="COLOR: #000000">wsock32.lib </span>
		</div>
		<br />winsock2.0<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">1</span><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">winsock2.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />#pragma comment(lib,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ws2_32.lib</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br /></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />或者<br /></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" />alt</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">f7 link</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">ws2_32.lib</span></div><img src ="http://www.cppblog.com/guanchanghui/aggbug/12785.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guanchanghui/" target="_blank">asdfastone</a> 2006-09-21 11:14 <a href="http://www.cppblog.com/guanchanghui/articles/12785.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>#pragma 预处理指令详解</title><link>http://www.cppblog.com/guanchanghui/articles/12784.html</link><dc:creator>asdfastone</dc:creator><author>asdfastone</author><pubDate>Thu, 21 Sep 2006 03:06:00 GMT</pubDate><guid>http://www.cppblog.com/guanchanghui/articles/12784.html</guid><description><![CDATA[
		<p>
				<font face="Courier New" size="2">#pragma  预处理指令详解    <br />     <br /> <br />    在所有的预处理指令中，#pragma 指令可能是最复杂的了，它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。<br />#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。<br />依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。  <br />    其格式一般为: #pragma  para  <br />    其中para为参数，下面来看一些常用的参数。  <br /> </font>
		</p>
		<p>
				<font face="Courier New" size="2">(1)message 参数</font>
		</p>
		<p>
				<font face="Courier New" size="2">    message参数是我最喜欢的一个参数，它能够在编译信息输出窗口中输出相应的信息，<br />这对于源代码信息的控制是非常重要的。其使用方法为：  <br />    #pragma  message("消息文本")  <br />    当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。  <br />    当我们在程序中定义了许多宏来控制源代码版本的时候，我们自己有可能都会忘记有没有正确的设置这些宏，<br />此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏,<br />可以用下面的方法:<br />    #ifdef  _X86  <br />    #pragma  message("_X86  macro  activated!")  <br />    #endif  <br />    我们定义了_X86这个宏以后，应用程序在编译时就会在编译输出窗口里显示"_86  macro  activated!"。<br />我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。  <br />       </font>
		</p>
		<p>
				<font face="Courier New" size="2">(2)另一个使用得比较多的pragma参数是code_seg</font>
		</p>
		<p>
				<font face="Courier New" size="2">    格式如：  <br />    #pragma  code_seg( ["section-name" [, "section-class"] ] )  <br />    它能够设置程序中函数代码存放的代码段，当我们开发驱动程序的时候就会使用到它。  <br /> </font>
		</p>
		<p>
				<font face="Courier New" size="2">(3)#pragma once  (比较常用)  </font>
		</p>
		<p>
				<font face="Courier New" size="2">    只要在头文件的最开始加入这条指令就能够保证头文件被编译一次，这条指令实际上在VC6中就已经有了，<br />但是考虑到兼容性并没有太多的使用它。  </font>
		</p>
		<p>
				<font face="Courier New" size="2">       <br />(4)#pragma  hdrstop</font>
		</p>
		<p>
				<font face="Courier New" size="2">    表示预编译头文件到此为止，后面的头文件不进行预编译。BCB可以预编译头文件以加快链接的速度，<br />但如果所有头文件都进行预编译又可能占太多磁盘空间，所以使用这个选项排除一些头文件。    <br />    有时单元之间有依赖关系，比如单元A依赖单元B，所以单元B要先于单元A编译。<br />你可以用#pragma  startup指定编译优先级，如果使用了#pragma  package(smart_init)，<br />BCB就会根据优先级的大小先后编译。    </font>
		</p>
		<p>
				<font face="Courier New" size="2">       <br />(5)#pragma  resource  "*.dfm"</font>
		</p>
		<p>
				<font face="Courier New" size="2">    表示把*.dfm文件中的资源加入工程。*.dfm中包括窗体  <br />外观的定义。    </font>
		</p>
		<p>
				<font face="Courier New" size="2">         <br />(6)#pragma  warning( disable: 4507 34; once: 4385; error: 164 )<br />  <br />    等价于：  <br />    #pragma  warning( disable: 4507 34 )    //  不显示4507和34号警告信息  <br />    #pragma  warning( once: 4385 )          //  4385号警告信息仅报告一次  <br />    #pragma  warning( error: 164 )          //  把164号警告信息作为一个错误。  </font>
		</p>
		<p>
				<font face="Courier New" size="2">    同时这个pragma  warning  也支持如下格式：  <br />    #pragma  warning( push [, n ] )  <br />    #pragma  warning( pop )  <br />    这里n代表一个警告等级(1---4)。  <br />    #pragma  warning( push )保存所有警告信息的现有的警告状态。  <br />    #pragma  warning( push, n )保存所有警告信息的现有的警告状态，并且把全局警告等级设定为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 />    //.......  <br />    #pragma  warning(  pop  )    <br />    在这段代码的最后，重新保存所有的警告信息(包括4705，4706和4707)。  </font>
		</p>
		<p>
				<br />
				<font face="Courier New" size="2">(7)#pragma  comment(...)  </font>
		</p>
		<p>
				<font face="Courier New" size="2">    该指令将一个注释记录放入一个对象文件或可执行文件中。  <br />常用的lib关键字，可以帮我们连入一个库文件。如：<br />    #pragma  comment(lib, "comctl32.lib")<br />    #pragma  comment(lib, "vfw32.lib")<br />    #pragma  comment(lib, "wsock32.lib")<br /> <br />   <br />   <br />每个编译程序可以用#pragma指令激活或终止该编译程序支持的一些编译功能。</font>
		</p>
		<p>
				<font face="Courier New" size="2">例如，对循环优化功能：  <br />#pragma  loop_opt(on)     //  激活  <br />#pragma  loop_opt(off)    //  终止  </font>
		</p>
		<p>
				<font face="Courier New" size="2">有时，程序中会有些函数会使编译器发出你熟知而想忽略的警告，<br />如“Parameter  xxx  is  never  used  in  function  xxx”，可以这样：  <br />#pragma  warn  —100         //  Turn  off  the  warning  message  for  warning  #100  <br />int  insert_record(REC  *r)  <br />{  /*  function  body  */  }  <br />#pragma  warn  +100          //  Turn  the  warning  message  for  warning  #100  back  on  <br />函数会产生一条有唯一特征码100的警告信息，如此可暂时终止该警告。  </font>
		</p>
		<p>
				<font face="Courier New" size="2">每个编译器对#pragma的实现不同，在一个编译器中有效在别的编译器中几乎无效。可从编译器的文档中查看。</font>
		</p>
		<p>
				<font face="Courier New" size="2">
				</font>
		</p>
		<p>
				<font face="Courier New" size="2">补充 —— #pragma pack 与 内存对齐问题</font>
		</p>
		<p>
				<br />
				<font face="Courier New" size="2">    许多实际的计算机系统对基本类型数据在内存中存放的位置有限制，它们会要求这些数据的首地址的值是某个数k<br />(通常它为4或8)的倍数，这就是所谓的内存对齐，而这个k则被称为该数据类型的对齐模数(alignment modulus)。</font>
		</p>
		<p>
				<font face="Courier New" size="2">    Win32平台下的微软C编译器(cl.exe for 80x86)在默认情况下采用如下的对齐规则: <br />    任何基本数据类型T的对齐模数就是T的大小，即sizeof(T)。比如对于double类型(8字节)，<br />就要求该类型数据的地址总是8的倍数，而char类型数据(1字节)则可以从任何一个地址开始。</font>
		</p>
		<p>
				<font face="Courier New" size="2">    Linux下的GCC奉行的是另外一套规则(在资料中查得，并未验证，如错误请指正):<br />    任何2字节大小(包括单字节吗?)的数据类型(比如short)的对齐模数是2，而其它所有超过2字节的数据类型<br />(比如long,double)都以4为对齐模数。</font>
		</p>
		<p>
				<font face="Courier New" size="2">    ANSI C规定一种结构类型的大小是它所有字段的大小以及字段之间或字段尾部的填充区大小之和。<br />填充区就是为了使结构体字段满足内存对齐要求而额外分配给结构体的空间。那么结构体本身有什么对齐要求吗？<br />有的，ANSI C标准规定结构体类型的对齐要求不能比它所有字段中要求最严格的那个宽松，可以更严格。</font>
		</p>
		<p>
				<br />
				<font face="Courier New" size="2">如何使用c/c++中的对齐选项</font>
		</p>
		<p>
				<font face="Courier New" size="2">    vc6中的编译选项有 /Zp[1|2|4|8|16] ，/Zp1表示以1字节边界对齐，相应的，/Zpn表示以n字节边界对齐。<br />n字节边界对齐的意思是说，一个成员的地址必须安排在成员的尺寸的整数倍地址上或者是n的整数倍地址上，取它们中的最小值。<br />也就是：<br />    min ( sizeof ( member ),  n)</font>
		</p>
		<p>
				<font face="Courier New" size="2">    实际上，1字节边界对齐也就表示了结构成员之间没有空洞。<br />    /Zpn选项是应用于整个工程的，影响所有的参与编译的结构。<br />    要使用这个选项，可以在vc6中打开工程属性页，c/c++页，选择Code Generation分类，在Struct member alignment可以选择。</font>
		</p>
		<p>
				<font face="Courier New" size="2">    要专门针对某些结构定义使用对齐选项，可以使用#pragma pack编译指令:</font>
		</p>
		<p>
				<br />
				<font face="Courier New" size="2">(1) #pragma  pack( [ n ] )</font>
		</p>
		<p>
				<font face="Courier New" size="2">    该指令指定结构和联合成员的紧凑对齐。而一个完整的转换单元的结构和联合的紧凑对齐由/Zp 选项设置。<br />紧凑对齐用pack编译指示在数据说明层设置。该编译指示在其出现后的第一个结构或联合说明处生效。<br />该编译指示对定义无效。<br />    当你使用#pragma  pack ( n ) 时, 这里n 为1、2、4、8 或16。<br />    第一个结构成员之后的每个结构成员都被存储在更小的成员类型或n 字节界限内。<br />如果你使用无参量的#pragma  pack, 结构成员被紧凑为以/Zp 指定的值。该缺省/Zp 紧凑值为/Zp8 。</font>
		</p>
		<p>
				<br />
				<font face="Courier New" size="2">(2) 编译器也支持以下增强型语法:<br />    #pragma  pack( [ [ { push | pop } , ] [ identifier, ] ] [ n] )</font>
		</p>
		<p>
				<font face="Courier New" size="2">    若不同的组件使用pack编译指示指定不同的紧凑对齐, 这个语法允许你把程序组件组合为一个单独的转换单元。<br />带push参量的pack编译指示的每次出现将当前的紧凑对齐存储到一个内部编译器堆栈中。<br />    编译指示的参量表从左到右读取。如果你使用push, 则当前紧凑值被存储起来; <br />如果你给出一个n 的值, 该值将成为新的紧凑值。若你指定一个标识符, 即你选定一个名称, <br />则该标识符将和这个新的的紧凑值联系起来。</font>
		</p>
		<p>
				<font face="Courier New" size="2">    带一个pop参量的pack编译指示的每次出现都会检索内部编译器堆栈顶的值,并且使该值为新的紧凑对齐值。<br />如果你使用pop参量且内部编译器堆栈是空的,则紧凑值为命令行给定的值, 并且将产生一个警告信息。<br />若你使用pop且指定一个n的值, 该值将成为新的紧凑值。若你使用p o p 且指定一个标识符, <br />所有存储在堆栈中的值将从栈中删除, 直到找到一个匹配的标识符, 这个与标识符相关的紧凑值也从栈中移出, <br />并且这个仅在标识符入栈之前存在的紧凑值成为新的紧凑值。如果未找到匹配的标识符, <br />将使用命令行设置的紧凑值, 并且将产生一个一级警告。缺省紧凑对齐为8 。</font>
		</p>
		<p>
				<font face="Courier New" size="2">   pack编译指示的新的增强功能让你编写头文件, 确保在遇到该头文件的前后的<br />紧凑值是一样的。</font>
		</p>
		<p>
				<br />
				<font face="Courier New" size="2">(3) 栈内存对齐</font>
		</p>
		<p>
				<font face="Courier New" size="2">    在vc6中栈的对齐方式不受结构成员对齐选项的影响。它总是保持对齐，而且对齐在4字节边界上。<br />//---------------------------------继续学习------------------------------------------------<br />在所有的预处理指令中，#Pragma  指令可能是最复杂的了，它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。  <br />其格式一般为:        #Pragma  Para  <br />       其中Para  为参数，下面来看一些常用的参数。  <br /><br />       <strong>(1)message  参数。</strong>  <br />       Message  参数是我最喜欢的一个参数，它能够在编译信息输出窗口中输出相应的信息，这对于源代码信息的控制是非常重要的。其使用方法为：  <br />             #Pragma  message(“消息文本”)  <br />             当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。  <br />       当我们在程序中定义了许多宏来控制源代码版本的时候，我们自己有可能都会忘记有没有正确的设置这些宏，此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法  <br />             #ifdef  _X86  <br />             #Pragma  message(“_X86  macro  activated!”)  <br />             #endif  <br />             当我们定义了_X86这个宏以后，应用程序在编译时就会在编译输出窗口里显示“_  <br />X86  macro  activated!”。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。  <br />       <br />     <strong>(2)另一个使用得比较多的pragma参数是code_seg。<br />          </strong>格式如：  <br />           #pragma  code_seg(  ["section-name"[,"section-class"]  ]  )  <br />           它能够设置程序中函数代码存放的代码段，当我们开发驱动程序的时候就会使用到它。  <br /><br />     <strong>(3)#pragma  once  (比较常用）  </strong><br />           只要在头文件的最开始加入这条指令就能够保证头文件被编译一次，这条指令实际上在VC6中就已经有了，但是考虑到兼容性并没有太多的使用它。  <br />       <br />     <strong>(4)#pragma  hdrstop表示预编译头文件到此为止，后面的头文件不进行预编译。<br />       </strong>BCB可以预编译头文件以加快链接的速度，但如果所有头文件都进行预编译又可能占太多磁盘空间，所以使用这个选项排除一些头文件。    <br />         有时单元之间有依赖关系，比如单元A依赖单元B，所以单元B要先于单元A编译。你可以用#pragma  startup指定编译优先级，如果使用了#pragma  package(smart_init)  ，BCB就会根据优先级的大小先后编译。    <br />       <br />     <strong>(5)#pragma  resource </strong> "*.dfm"表示把*.dfm文件中的资源加入工程。*.dfm中包括窗体  <br />外观的定义。    <br />         <br />    <strong> (6)#pragma  warning</strong>(  disable  :  4507  34;  once  :  4385;  error  :  164  )  <br />           等价于：  <br />           #pragma  warning(disable:4507  34)    //  不显示4507和34号警告信息  <br />           #pragma  warning(once:4385)                //  4385号警告信息仅报告一次  <br />           #pragma  warning(error:164)                //  把164号警告信息作为一个错误。  <br />           同时这个pragma  warning  也支持如下格式：  <br />           #pragma  warning(  push  [  ,n  ]  )  <br />           #pragma  warning(  pop  )  <br />           这里n代表一个警告等级(1---4)。  <br />           #pragma  warning(  push  )保存所有警告信息的现有的警告状态。  <br />           #pragma  warning(  push,  n)保存所有警告信息的现有的警告状态，并且把全局警告  <br />等级设定为n。    <br />           #pragma  warning(  pop  )向栈中弹出最后一个警告信息，在入栈和出栈之间所作的  <br />一切改动取消。例如：  <br />           #pragma  warning(  push  )  <br />           #pragma  warning(  disable  :  4705  )  <br />           #pragma  warning(  disable  :  4706  )  <br />           #pragma  warning(  disable  :  4707  )  <br />           //.......  <br />           #pragma  warning(  pop  )    <br />           在这段代码的最后，重新保存所有的警告信息(包括4705，4706和4707)。  <br /><br /><strong>   （7）pragma  comment(...)  <br /></strong>             该指令将一个注释记录放入一个对象文件或可执行文件中。  <br />           常用的lib关键字，可以帮我们连入一个库文件。  <br /><br /><strong>   （8）用pragma导出dll中的函数<br /></strong><span>    传统的到出 DLL 函数的方法是使用模块定义文件 (.def)，Visual C++ 提供了更简洁方便的方法，那就是“__declspec()”关键字后面跟“dllexport”，告诉连接去要导出这个函数，例如：__declspec(dllexport) int __stdcall MyExportFunction(int iTest);    把“__declspec(dllexport)”放在函数声明的最前面，连接生成的 DLL 就会导出函数<a href="mailto:“_MyExportFunction@4"><font color="#000080">“_MyExportFunction@4</font></a>”。<br />    上面的导出函数的名称也许不是我的希望的，我们希望导出的是原版的“MyExportFunction”。还好，VC 提供了一个预处理指示符“#pragma”来指定连接选项 (不仅仅是这一个功能，还有很多指示功能) ，如下：<br />    #pragma comment(linker,"/EXPORT:MyExportFunction=_MyExportFunction@4")<br />    这下就天如人愿了：）。如果你想指定导出的顺序，或者只将函数导出为序号，没有 Entryname，这个预处理指示符 (确切地说是连接器) 都能够实现，看看 MSDN 的语法说明：<br />       /EXPORT:entryname[,@ordinal[,NONAME]][,DATA]<br />     @ordinal 指定顺序；NONAME 指定只将函数导出为序号；DATA 关键字指定导出项为数据项。<br /><br />  <strong> （9）每个编译程序可以用#pragma指令激活或终止该编译程序支持的一些编译功能。<br />     </strong>例如，对循环优化功能：  <br />     #pragma  loop_opt(on)            //  激活  <br />     #pragma  loop_opt(off)    //  终止  <br />有时，程序中会有些函数会使编译器发出你熟知而想忽略的警告，如“Parameter  xxx  is  never  used  in  function  xxx”，可以这样：  <br />#pragma  warn  —100            //  Turn  off  the  warning  message  for  warning  #100  <br />int  insert_record(REC  *r)  <br />{  /*  function  body  */  }  <br />#pragma  warn  +100                        //  Turn  the  warning  message  for  warning  #100  back  on  <br />函数会产生一条有唯一特征码100的警告信息，如此可暂时终止该警告。  <br />每个编译器对#pragma的实现不同，在一个编译器中有效在别的编译器中几乎无效。可从编译器的文档中查看。  <br />一个很重要的参数<br />#pragma pack(n)<br />数据边界对齐方式:<br />以如下结构为例: struct {<br />                   char a;<br />                   WORD b;<br />                   DWORD c;<br />                   char d;<br />                  }<br />在Windows默认结构大小: sizeof(struct) = 4+4+4+4=16;<br />与#pragma pack(4)一样<br />若设为 #pragma pack(1), 则结构大小: sizeof(struct) = 1+2+4+1=8;<br />若设为 #pragma pack(2), 则结构大小: sizeof(struct) = 2+2+4+2=10;<br />在#pragma pack(1)时:空间是节省了,但访问速度降低了;<br />有什么用处???<br />在系统通讯中,如和硬件设备通信,和其他的操作系统进行通信时等,必须保证双方的一致性。<br /></span><br /></font>
		</p>
		<p>
				<font face="Courier New" size="2">
				</font>
		</p>
		<br />
<img src ="http://www.cppblog.com/guanchanghui/aggbug/12784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guanchanghui/" target="_blank">asdfastone</a> 2006-09-21 11:06 <a href="http://www.cppblog.com/guanchanghui/articles/12784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解析#pragma指令</title><link>http://www.cppblog.com/guanchanghui/articles/12783.html</link><dc:creator>asdfastone</dc:creator><author>asdfastone</author><pubDate>Thu, 21 Sep 2006 03:01:00 GMT</pubDate><guid>http://www.cppblog.com/guanchanghui/articles/12783.html</guid><description><![CDATA[在所有的预处理指令中，#Pragma 指令可能是最复杂的了，它的作用是设定编译器的状态或 
<p>者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与</p><p>C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器</p><p>或操作系统专有的,且对于每个编译器都是不同的。</p><p>其格式一般为: #Pragma Para</p><p>其中Para 为参数，下面来看一些常用的参数。</p><p> </p><p>(1)message 参数。 Message 参数是我最喜欢的一个参数，它能够在编译信息输出窗</p><p>口中输出相应的信息，这对于源代码信息的控制是非常重要的。其使用方法为：</p><p><br />#Pragma message(“消息文本”)</p><p>当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。</p><p>当我们在程序中定义了许多宏来控制源代码版本的时候，我们自己有可能都会忘记有没有正</p><p>确的设置这些宏，此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自</p><p>己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法</p><p>#ifdef _X86</p><p>#Pragma message(“_X86 macro activated!”)</p><p>#endif</p><p>当我们定义了_X86这个宏以后，应用程序在编译时就会在编译输出窗口里显示“_</p><p>X86 macro activated!”。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了</p><p>。</p><p> </p><p>(2)另一个使用得比较多的pragma参数是code_seg。格式如：</p><p>#pragma code_seg( [\section-name\[,\section-class\] ] )</p><p>它能够设置程序中函数代码存放的代码段，当我们开发驱动程序的时候就会使用到它。</p><p> </p><p>(3)#pragma once (比较常用）</p><p>只要在头文件的最开始加入这条指令就能够保证头文件被编译一次，这条指令实际上在VC6</p><p>中就已经有了，但是考虑到兼容性并没有太多的使用它。</p><p> </p><p>(4)#pragma hdrstop表示预编译头文件到此为止，后面的头文件不进行预编译。BCB可以预</p><p>编译头文件以加快链接的速度，但如果所有头文件都进行预编译又可能占太多磁盘空间，所</p><p><br />以使用这个选项排除一些头文件。</p><p>有时单元之间有依赖关系，比如单元A依赖单元B，所以单元B要先于单元A编译。你可以用#p</p><p>ragma startup指定编译优先级，如果使用了#pragma package(smart_init) ，BCB就会根据</p><p>优先级的大小先后编译。</p><p> </p><p>(5)#pragma resource \*.dfm\表示把*.dfm文件中的资源加入工程。*.dfm中包括窗体</p><p>外观的定义。</p><p> </p><p>(6)#pragma warning( disable : 4507 34; once : 4385; error : 164 )</p><p>等价于：</p><p>#pragma warning(disable:4507 34) // 不显示4507和34号警告信息</p><p>#pragma warning(once:4385) // 4385号警告信息仅报告一次</p><p>#pragma warning(error:164) // 把164号警告信息作为一个错误。</p><p>同时这个pragma warning 也支持如下格式：</p><p>#pragma warning( push [ ,n ] )</p><p>#pragma warning( pop )</p><p>这里n代表一个警告等级(1---4)。</p><p>#pragma warning( push )保存所有警告信息的现有的警告状态。</p><p>#pragma warning( push, n)保存所有警告信息的现有的警告状态，并且把全局警告</p><p>等级设定为n。</p><p>#pragma warning( pop )向栈中弹出最后一个警告信息，在入栈和出栈之间所作的</p><p>一切改动取消。例如：</p><p><br />#pragma warning( push )</p><p>#pragma warning( disable : 4705 )</p><p>#pragma warning( disable : 4706 )</p><p>#pragma warning( disable : 4707 )</p><p>//.......</p><p>#pragma warning( pop )</p><p>在这段代码的最后，重新保存所有的警告信息(包括4705，4706和4707)。</p><p>（7）pragma comment(...)</p><p>该指令将一个注释记录放入一个对象文件或可执行文件中。</p><p>常用的lib关键字，可以帮我们连入一个库文件。</p><p>（8）·通过#pragma pack(n)改变C编译器的字节对齐方式 <br />在C语言中，结构是一种复合数据类型，其构成元素既可以是基本数据类型（如int、long、float等）的变量，也可以是一些复合数据类型（如数组、结构、联合等）的数据单元。在结构中，编译器为结构的每个成员按其自然对界（alignment）条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储，第一个成员的地址和整个结构的地址相同。</p><p>     例如，下面的结构各成员空间分配情况：<br />struct test <br />{<br />     char x1;<br />     short x2;<br />     float x3;<br />     char x4;<br />};<br />     结构的第一个成员x1，其偏移地址为0，占据了第1个字节。第二个成员x2为short类型，其起始地址必须2字节对界，因此，编译器在x2和x1之间填充了一个空字节。结构的第三个成员x3和第四个成员x4恰好落在其自然对界地址上，在它们前面不需要额外的填充字节。在test结构中，成员x3要求4字节对界，是该结构所有成员中要求的最大对界单元，因而test结构的自然对界条件为4字节，编译器在成员x4后面填充了3个空字节。整个结构所占据空间为12字节。更改C编译器的缺省字节对齐方式<br />     在缺省情况下，C编译器为每一个变量或是数据单元按其自然对界条件分配空间。一般地，可以通过下面的方法来改变缺省的对界条件：<br />　　· 使用伪指令#pragma pack (n)，C编译器将按照n个字节对齐。<br />     · 使用伪指令#pragma pack ()，取消自定义字节对齐方式。</p><p>     另外，还有如下的一种方式：<br />     · __attribute((aligned (n)))，让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n，则按照最大成员的长度来对齐。<br />     · __attribute__ ((packed))，取消结构在编译过程中的优化对齐，按照实际占用字节数进行对齐。</p><p>以上的n = 1, 2, 4, 8, 16... 第一种方式较为常见。</p><p>应用实例</p><p>　　在网络协议编程中，经常会处理不同协议的数据报文。一种方法是通过指针偏移的方法来得到各种信息，但这样做不仅编程复杂，而且一旦协议有变化，程序修改起来也比较麻烦。在了解了编译器对结构空间的分配原则之后，我们完全可以利用这一特性定义自己的协议结构，通过访问结构的成员来获取各种信息。这样做，不仅简化了编程，而且即使协议发生变化，我们也只需修改协议结构的定义即可，其它程序无需修改，省时省力。下面以TCP协议首部为例，说明如何定义协议结构。其协议结构定义如下：</p><p>#pragma pack(1) // 按照1字节方式进行对齐<br />struct TCPHEADER <br />{<br />     short SrcPort; // 16位源端口号<br />     short DstPort; // 16位目的端口号<br />     int SerialNo; // 32位序列号<br />     int AckNo; // 32位确认号<br />     unsigned char HaderLen : 4; // 4位首部长度<br />     unsigned char Reserved1 : 4; // 保留6位中的4位<br />     unsigned char Reserved2 : 2; // 保留6位中的2位<br />     unsigned char URG : 1;<br />     unsigned char ACK : 1;<br />     unsigned char PSH : 1;<br />     unsigned char RST : 1;<br />     unsigned char SYN : 1;<br />     unsigned char FIN : 1;<br />     short WindowSize; // 16位窗口大小<br />     short TcpChkSum; // 16位TCP检验和<br />     short UrgentPointer; // 16位紧急指针<br />}; <br />#pragma pack() // 取消1字节对齐方式 </p><p></p><p>-- 选择自 vcforever 的 Blog </p><p>在编写程序的时候,我们经常要用到#pragma指令来设定编译器的状态或者是指示编译器完成一些特定的动作.<br />下面介绍了一下该指令的一些常用参数,希望对大家有所帮助!</p><p><strong>一. message 参数</strong>。 </p><p><font color="#000000">message </font><br />它能够在编译信息输出窗  <br />口中输出相应的信息，这对于源代码信息的控制是非常重要的。</p><p>其使用方法为：    #pragma message("消息文本")  </p><p>当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。  <br />当我们在程序中定义了许多宏来控制源代码版本的时候，我们自己有可能都会忘记有没有正确的设置这些宏，此时我们可以用这条<br />指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法  <br />#ifdef _X86  <br />#pragma message("_X86 macro activated!")  <br />#endif  <br />当我们定义了_X86这个宏以后，应用程序在编译时就会在编译输出窗口里显示"_  <br />X86 macro activated!"。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了  <br />    <br /><strong>二. 另一个使用得比较多的#pragma参数是code_seg</strong>。</p><p>格式如：</p><p>#pragma code_seg( [ [ { push | pop}, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] ) <br />该指令用来指定函数在.obj文件中存放的节,观察OBJ文件可以使用VC自带的dumpbin命令行程序,函数在.obj文件中默认的存放节<br />为.text节<br />如果code_seg没有带参数的话,则函数存放在.text节中<br />push (可选参数) 将一个记录放到内部编译器的堆栈中,可选参数可以为一个标识符或者节名<br />pop(可选参数) 将一个记录从堆栈顶端弹出,该记录可以为一个标识符或者节名<br />identifier (可选参数) 当使用push指令时,为压入堆栈的记录指派的一个标识符,当该标识符被删除的时候和其相关的堆栈中的记录将被弹出堆栈 <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 />}<br /><br /><strong>三. #pragma once (比较常用）</strong>  </p><p>这是一个比较常用的指令,只要在头文件的最开始加入这条指令就能够保证头文件被编译一次<br />    <br /><strong>四. #pragma hdrstop表示预编译头文件到此为止，后面的头文件不进行预编译</strong>。</p><p>BCB可以预编译头文件以加快链接的速度，但如果所有头文件都进行预编译又可能占太多磁盘空间，所以使用这个选项排除一些头文件。   <br />有时单元之间有依赖关系，比如单元A依赖单元B，所以单元B要先于单元A编译。你可以用#pragma startup指定编译优先级，<br />如果使用了#pragma package(smart_init) ，BCB就会根据优先级的大小先后编译。   <br /><br /><strong>五. #pragma warning指令</strong></p><p>该指令允许有选择性的修改编译器的警告消息的行为<br />指令格式如下:<br />#pragma warning( warning-specifier : warning-number-list [; warning-specifier : warning-number-list...]<br />#pragma warning( push[ ,n ] )<br />#pragma warning( pop )</p><p>主要用到的警告表示有如下几个:</p><p>once:只显示一次(警告/错误等)消息<br />default:重置编译器的警告行为到默认状态<br />1,2,3,4:四个警告级别<br />disable:禁止指定的警告信息<br />error:将指定的警告信息作为错误报告</p><p>如果大家对上面的解释不是很理解,可以参考一下下面的例子及说明<br /> <br />#pragma warning( disable : 4507 34; once : 4385; error : 164 )  <br />等价于：  <br />#pragma warning(disable:4507 34)  // 不显示4507和34号警告信息  <br />#pragma warning(once:4385)        // 4385号警告信息仅报告一次  <br />#pragma warning(error:164)        // 把164号警告信息作为一个错误。  <br />同时这个pragma warning 也支持如下格式：  <br />#pragma warning( push [ ,n ] )  <br />#pragma warning( pop )  <br />这里n代表一个警告等级(1---4)。  <br />#pragma warning( push )保存所有警告信息的现有的警告状态。  <br />#pragma warning( push, n)保存所有警告信息的现有的警告状态，并且把全局警告等级设定为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>在这段代码的最后，重新保存所有的警告信息(包括4705，4706和4707)</p><p>在使用标准C++进行编程的时候经常会得到很多的警告信息,而这些警告信息都是不必要的提示,所以我们可以使用#pragma warning(disable:4786)来禁止该类型的警告在vc中使用ADO的时候也会得到不必要的警告信息,这个时候我们可以通过#pragma warning(disable:4146)来消除该类型的警告信息</p><p><strong>六. pragma comment(...)</strong><br />该指令的格式为：  #pragma comment( "comment-type" [, commentstring] )<br />     该指令将一个注释记录放入一个对象文件或可执行文件中,comment-type(注释类型):可以指定为五种预定义的标识符的其中一种<br />    五种预定义的标识符为:</p><p>     compiler:将编译器的版本号和名称放入目标文件中,本条注释记录将被编译器忽略<br />                  如果你为该记录类型提供了commentstring参数,编译器将会产生一个警告<br />                  例如:#pragma comment( compiler )</p><p>     exestr:将commentstring参数放入目标文件中,在链接的时候这个字符串将被放入到可执行文件中,当操作系统加载可执行文件的时候,该参数字符串不会被加载到内存中.但是,该字符串可以被dumpbin之类的程序查找出并打印出来,你可以用这个标识符将版本号码之类的信息嵌入到可       执行文件中!</p><p>     lib:这是一个非常常用的关键字,用来将一个库文件链接到目标文件中常用的lib关键字，可以帮我们连入一个库文件。  <br />         例如:               #pragma comment(lib, "user32.lib")  <br />                               该指令用来将user32.lib库文件加入到本工程中</p><p><br />     linker:将一个链接选项放入目标文件中,你可以使用这个指令来代替由命令行传入的或者在开发环境中设置的链接选项,你可以指定/include选项来强制包含某个对象,例如:       #pragma comment(linker, "/include:__mySymbol")</p><p>               你可以在程序中设置下列链接选项</p><p>                          /DEFAULTLIB <br />                          /EXPORT <br />                          /INCLUDE <br />                          /MERGE <br />                         /SECTION </p><p><font face="Tahoma"></font><br />              这些选项在这里就不一一说明了,详细信息请看msdn!</p><p>      user:将一般的注释信息放入目标文件中commentstring参数包含注释的文本信息,这个注释记录将被链接器忽略<br />      例如:     #pragma comment( user, "Compiled on " __DATE__ " at " __TIME__ )</p><img src ="http://www.cppblog.com/guanchanghui/aggbug/12783.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guanchanghui/" target="_blank">asdfastone</a> 2006-09-21 11:01 <a href="http://www.cppblog.com/guanchanghui/articles/12783.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>#pragma伪指令及结构体对界（Alignment）</title><link>http://www.cppblog.com/guanchanghui/articles/12782.html</link><dc:creator>asdfastone</dc:creator><author>asdfastone</author><pubDate>Thu, 21 Sep 2006 02:51:00 GMT</pubDate><guid>http://www.cppblog.com/guanchanghui/articles/12782.html</guid><description><![CDATA[
		<h3>#pragma伪指令及结构体对界（Alignment）</h3>
		<h3>
				<br />第一部分 关于对界</h3>
		<p>使用伪指令对<span class="Code">#pragma pack (1)</span><span class="Code">#pragma pack</span><span class="Code"><br /></span><span class="Code"><br />#include "stdafx.h"<br />#include &lt;stdio.h&gt;<br />#pragma pack (1)<br />typedef struct test <br />{ <br /> char x1;<br /> short x2;<br /> float x3;<br /> char x4; <br />};<br />test mytest;<br />//#pragma pack(1)<br />void testf(int**p) //函数参数为指向指针的指针p  <br />{<br /> *p+=1;   <br />} <br />int main(int argc, char *argv[])<br />{<br />  <br /> printf("Hello, world\n");<br /> int *n,m[2];   <br /> n=m;   <br /> m[0]=1;   <br /> m[1]=8;   <br /> testf(&amp;n); //here, &amp;n will replace p.  <br /> printf("Data value is %d \n",*n);//pointer n move to point next data. <br /> <br /> *n =sizeof(mytest);<br /> printf("sizeof(mytest) is %d \n",m[1]);<br /> return 0;<br />} </span></p>
		<p> </p>
		<p> </p>
		<p> 以上代码输出“sizeof(mytest) is 8”。<font style="BACKGROUND-COLOR: #ff9933" face="Courier New" color="#000066">#pragma pack (1)</font>指定以1字节对齐，也就是不填充，相当于有的编译器packed关键字的使用。<br />请注意<font style="BACKGROUND-COLOR: #ff9933" face="Courier New" color="#000066">#pragma pack (n)</font>：n = 1,2,4,8...如果大于结构体中最大成员字节数，则不起作用。例子如下：<br /><span class="Code">#pragma pack (8)<br />typedef struct test <br />{ <br /> char x1;<br /> short x2;<br /> float x3;<br /> char x4; <br />};<br />test mytest;<br />//#pragma pack(1)</span></p>
		<p>sizeof(mytest)等于12,以x3四字节为对界数并不用8字节对界。特别注意：对界过程并不是最大成员乘以成员个数（这里不是4*4=16），而是从头到尾依次对界，总的原则是尽量节省连续的存储空间。如上结构体对界过程如下：x1与x2，x1后填充一字节，x3正好位于对界地址上且长度正好是对界数，则无填充，x4位于对界地址上，后填充直下一个对界地址，即填充后3个字节。</p>
		<p>接下来，我们一起用一道号称是MicroSoft ,IBM都出过的考题复习以下：<br />1. #include &lt;iostream.h&gt;<br /><br />2. #pragma pack(8)<br />3. struct example1<br />4. {<br />5. short a;<br />6. long b;<br />7. };<br /><br />8. struct example2<br />9. {<br />10. char c;<br />11. example1 struct1;<br /> 12. short e;    <br />13. };<br />14. #pragma pack()<br /><br />15. int main(int argc, char* argv[])<br />16. {<br /> 17. example2 struct2;<br /><br />18. cout &lt;&lt; sizeof(example1) &lt;&lt; endl;<br />19. cout &lt;&lt; sizeof(example2) &lt;&lt; endl;<br />20. cout &lt;&lt; (unsigned int)(&amp;struct2.struct1) - (unsigned int)(&amp;struct2) <br />&lt;&lt; endl;<br /><br />21. return 0;<br />22. } </p>
		<p>问程序的输出结果是什么？ 答案是：<br />8<br />16<br />4 <br />做这个题，记住前面提到的原则：<span style="FONT-WEIGHT: bold"><font size="4">从头到尾依次对界，首先确定对界数（最大成员长度小于pack指定数时，以最大成员长度为准）；总的原则是尽量节省连续的存储空间。另外，嵌套对界的，被嵌套对象先对界。</font></span></p>
		<h1>第二部分 关于#pragma伪指令</h1>
		<div>（以下资源采编自网络）</div>
		<div>#pragma指令来设定编译器的状态或者是指示编译器完成一些特定的动作.以下介绍一下该指令的一些常用参数。</div>
		<h2>一. #pragma参数 message message</h2>
		<p>它能够在编译信息输出窗 口中输出相应的信息，这对于源代码信息的控制是非常重要的。其使用方法为：#pragma message(“消息文本”) <br />当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。  <br />当我们在程序中定义了许多宏来控制源代码版本的时候，我们自己有可能都会忘记有没有正确的设置这些宏，此时我们可以用这条<br />指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法  <br />#ifdef _X86  <br />#pragma message(“_X86 macro activated!”)  <br />#endif  <br />当我们定义了_X86这个宏以后，应用程序在编译时就会在编译输出窗口里显示“_  <br />X86 macro activated!”。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了  </p>
		<h2>二. #pragma常用参数code_seg</h2>
		<div>格式如：  </div>
		<div>#pragma code_seg( [ [ { push | pop}, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] ) <br />该指令用来指定函数在.obj文件中存放的节,观察OBJ文件可以使用VC自带的dumpbin命令行程序,函数在.obj文件中默认的存放节<br />为.text节<br />如果code_seg没有带参数的话,则函数存放在.text节中<br />push (可选参数) 将一个记录放到内部编译器的堆栈中,可选参数可以为一个标识符或者节名<br />pop(可选参数) 将一个记录从堆栈顶端弹出,该记录可以为一个标识符或者节名<br />identifier (可选参数) 当使用push指令时,为压入堆栈的记录指派的一个标识符,当该标识符被删除的时候和其相关的堆栈中的记录将被弹出堆栈 <br />"segment-name" (可选参数) 表示函数存放的节名<br />例如:<br />//默认情况下,函数被存放在.text节中<br />void func1() {                  // stored in .text<br />}</div>
		<div>//将函数存放在.my_data1节中<br />#pragma code_seg(".my_data1")<br />void func2() {                  // stored in my_data1<br />}</div>
		<div>//r1为标识符,将函数放入.my_data2节中<br />#pragma code_seg(push, r1, ".my_data2")<br />void func3() {                  // stored in my_data2<br />}</div>
		<div>int main() {<br />}</div>
		<h2>三. #pragma once</h2>
		<div>这是一个比较常用的指令,只要在头文件的最开始加入这条指令就能够保证头文件被编译一次</div>
		<div> </div>
		<h2>四. #pragma hdrstop表示预编译头文件停止。</h2>
		<div>BCB可以预编译头文件以加快链接的速度，但如果所有头文件都进行预编译又可能占太多磁盘空间，所以使用这个选项排除一些头文件。   <br />有时单元之间有依赖关系，比如单元A依赖单元B，所以单元B要先于单元A编译。你可以用#pragma startup指定编译优先级，<br />如果使用了#pragma package(smart_init) ，BCB就会根据优先级的大小先后编译。</div>
		<h2>   <br /><span>五</span><span>. #pragma warning</span><span>指令</span></h2>
		<div>该指令允许有选择性的修改编译器的警告消息的行为</div>
		<div>
				<br />指令格式如下:<br />#pragma warning( warning-specifier : warning-number-list [; warning-specifier : warning-number-list...]<br />#pragma warning( push[ ,n ] )<br />#pragma warning( pop )</div>
		<div>主要用到的警告表示有如下几个:</div>
		<div>once:只显示一次(警告/错误等)消息<br />default:重置编译器的警告行为到默认状态<br />1,2,3,4:四个警告级别<br />disable:禁止指定的警告信息<br />error:将指定的警告信息作为错误报告</div>
		<div>如果大家对上面的解释不是很理解,可以参考一下下面的例子及说明<br /> <br />#pragma warning( disable : 4507 34; once : 4385; error : 164 )  <br />等价于：  <br />#pragma warning(disable:4507 34)  // 不显示4507和34号警告信息  <br />#pragma warning(once:4385)        // 4385号警告信息仅报告一次  <br />#pragma warning(error:164)        // 把164号警告信息作为一个错误。  <br />同时这个pragma warning 也支持如下格式：  <br />#pragma warning( push [ ,n ] )  <br />#pragma warning( pop )  <br />这里n代表一个警告等级(1---4)。  <br />#pragma warning( push )保存所有警告信息的现有的警告状态。  <br />#pragma warning( push, n)保存所有警告信息的现有的警告状态，并且把全局警告  <br />等级设定为n。   <br />#pragma warning( pop )向栈中弹出最后一个警告信息，在入栈和出栈之间所作的  <br />一切改动取消。例如：  <br />#pragma warning( push )  <br />#pragma warning( disable : 4705 )  <br />#pragma warning( disable : 4706 )  <br />#pragma warning( disable : 4707 )  <br />#pragma warning( pop )</div>
		<div>在这段代码的最后，重新保存所有的警告信息(包括4705，4706和4707)</div>
		<div>在使用标准C++进行编程的时候经常会得到很多的警告信息,而这些警告信息都是不必要的提示,<br />所以我们可以使用#pragma warning(disable:4786)来禁止该类型的警告</div>
		<div>在vc中使用ADO的时候也会得到不必要的警告信息,这个时候我们可以通过<br />#pragma warning(disable:4146)来消除该类型的警告信息</div>
		<div>
				<strong>
						<font size="5">六. pragma comment(...)</font>
				</strong>
		</div>
		<div>该指令的格式为<br />#pragma comment( "comment-type" [, commentstring] )<br />  </div>
		<div>该指令将一个注释记录放入一个对象文件或可执行文件中,<br />comment-type(注释类型):可以指定为五种预定义的标识符的其中一种<br />五种预定义的标识符为:</div>
		<div>compiler:将编译器的版本号和名称放入目标文件中,本条注释记录将被编译器忽略<br />         如果你为该记录类型提供了commentstring参数,编译器将会产生一个警告<br />例如:#pragma comment( compiler )</div>
		<div>exestr:将commentstring参数放入目标文件中,在链接的时候这个字符串将被放入到可执行文件中,<br />       当操作系统加载可执行文件的时候,该参数字符串不会被加载到内存中.但是,该字符串可以被<br />       dumpbin之类的程序查找出并打印出来,你可以用这个标识符将版本号码之类的信息嵌入到可<br />       执行文件中!</div>
		<div>lib:这是一个非常常用的关键字,用来将一个库文件链接到目标文件中</div>
		<div>
				<br />常用的lib关键字，可以帮我们连入一个库文件。  <br />例如:<br />#pragma comment(lib, "user32.lib")  <br />该指令用来将user32.lib库文件加入到本工程中</div>
		<div>
				<br />linker:将一个链接选项放入目标文件中,你可以使用这个指令来代替由命令行传入的或者在开发环境中<br />       设置的链接选项,你可以指定/include选项来强制包含某个对象,例如:<br />       #pragma comment(linker, "/include:__mySymbol")</div>
		<div>你可以在程序中设置下列链接选项</div>
		<div>/DEFAULTLIB <br />/EXPORT <br />/INCLUDE <br />/MERGE <br />/SECTION <br />这些选项在这里就不一一说明了,详细信息请看msdn!</div>
		<div>user:将一般的注释信息放入目标文件中commentstring参数包含注释的文本信息,这个注释记录将被链接器忽略<br />例如:<br />#pragma comment( user, "Compiled on " __DATE__ " at " __TIME__ )</div>
		<br />
		<br />
		<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=845085</p>
		<div class="postFoot">
				<script src="http://localhost:82/PromoteIcon.aspx?id=845085">
				</script>
[<a href="javascript:StorePage()">点击此处收藏本文</a>]   James Deng发表于 2006年06月28日 11:06:00 </div>
		<link href="http://blog.csdn.net/yueyahe/Services/Pingback.aspx" rel="pingback" />
		<!--<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"xmlns:dc="http://purl.org/dc/elements/1.1/"xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"><rdf:Descriptionrdf:about="http://blog.csdn.net/yueyahe/archive/2006/06/28/845085.aspx"dc:identifier="http://blog.csdn.net/yueyahe/archive/2006/06/28/845085.aspx"dc:title="#pragma伪指令及结构体对界（Alignment）"trackback:ping="http://tb.blog.csdn.net/TrackBack.aspx?PostId=845085" /></rdf:RDF>-->
		<script><![CDATA[unction hide(){showComment();}]]&gt;</script>
		<br />
		<div class="post">
				<div class="postTitle">相关文章：</div>
				<ul class="postText">
						<li>
								<a href="http://blog.csdn.net/scrub/archive/2005/10/02/494171.aspx" target="_blank">解析#pragma指令</a> 2005-10-02 <a href="http://blog.csdn.net/scrub/" target="_blank">scrub</a></li>
						<li>
								<a href="http://blog.csdn.net/tiger119/archive/2005/02/04/279907.aspx" target="_blank">VC中预处理指令的详解</a> 2005-02-04 <a href="http://blog.csdn.net/tiger119/" target="_blank">tiger119</a></li>
						<li>
								<a href="http://blog.csdn.net/hustli/archive/2003/06/30/19353.aspx" target="_blank">解析#pragma指令</a> 2003-06-30 <a href="http://blog.csdn.net/hustli/" target="_blank">hustli</a></li>
						<li>
								<a href="http://blog.csdn.net/fisher_jiang/archive/2006/06/04/773215.aspx" target="_blank">#pragma预处理指令详解</a> 2006-06-04 <a href="http://blog.csdn.net/fisher_jiang/" target="_blank">fisher_jiang</a></li>
						<li>
								<a href="http://blog.csdn.net/jx_kingwei/archive/2005/04/28/367312.aspx" target="_blank">#pragma 预处理指令详解</a> 2005-04-28 <a href="http://blog.csdn.net/jx_kingwei/" target="_blank">jx_kingwei</a></li>
				</ul>
		</div>
<img src ="http://www.cppblog.com/guanchanghui/aggbug/12782.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guanchanghui/" target="_blank">asdfastone</a> 2006-09-21 10:51 <a href="http://www.cppblog.com/guanchanghui/articles/12782.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hierarchy Chart Categories, About the Microsoft Foundation Classes</title><link>http://www.cppblog.com/guanchanghui/articles/12700.html</link><dc:creator>asdfastone</dc:creator><author>asdfastone</author><pubDate>Tue, 19 Sep 2006 04:13:00 GMT</pubDate><guid>http://www.cppblog.com/guanchanghui/articles/12700.html</guid><description><![CDATA[
		<font face="Verdana" size="2"> </font>
		<h1>
				<a name="_mfc_hierarchy_chart">
				</a>
				<sup>
				</sup>Hierarchy Chart</h1>
		<p>
				<img src="mk:@MSITStore:D:\Microsoft%20Visual%20Studio\MSDN\2001OCT\1033\vcmfc.chm::/html/vc369q1_v6.gif" border="0" />
		</p>
		<p>
				<a href="mk:@MSITStore:D:\Microsoft%20Visual%20Studio\MSDN\2001OCT\1033\vcmfc.chm::/html/_mfc_about_the_microsoft_foundation_classes.htm">
				</a> </p>
		<!--FOOTER_START-->
		<script language="JavaScript" src="MS-ITS:dsmsdn.chm::/html/msdn_footer.js">
		</script>
<img src ="http://www.cppblog.com/guanchanghui/aggbug/12700.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/guanchanghui/" target="_blank">asdfastone</a> 2006-09-19 12:13 <a href="http://www.cppblog.com/guanchanghui/articles/12700.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>