




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、#pragma预处理命令#pragma可以说是C+中最复杂的预处理指令了,下面是最常用的几个#pragma指令: #pragma comment(lib,XXX.lib) 表示链接XXX.lib这个库,和在工程设置里写上XXX.lib的效果一样。 #pragma comment(linker,/ENTRY:main_function) 表示指定链接器选项/ENTRY:main_function #pragma once 表示这个文件只被包含一次 #pragma warning(disable:4705) 表示屏蔽警告4705 C和C+程序的每次执行都支持其所在的主机或操作系统所具有的一些独特的
2、特点。例如,有些程序需要精确控制数据存放的内存区域或控制某个函数接收的参数。#pragma为编译器提供了一种在不同机器和操作系统上编译以保持C和C+完全兼容的方法。#pragma是由机器和相关的操作系统定义的,通常对每个编译器来说是不同的。 如果编译器遇到不认识的pragma指令,将给出警告信息,然后继续编译。Microsoft C and C+ 的编译器可识别以下指令:alloc_text, auto_inline,bss_seg,check_stack,code_seg,comment,component,conform,const_seg,data_seg,deprecated, fen
3、v_access,float_control,fp_contract,function,hdrstop,include_alias,init_seg,inline_depth,inline_recursion,intrinsic, make_public,managed,message,omp,once,optimize,pack,pointers_to_members,pop_macro,push_macro,region, endregion,runtime_checks,section,setlocale,strict_gs_check,unmanaged,vtordisp,warnin
4、g。其中conform,init_seg, pointers_to_members,vtordisp仅被C+编译器支持。 以下是常用的pragma指令的详细解释。 1.#pragma once。保证所在文件只会被包含一次,它是基于磁盘文件的,而#ifndef则是基于宏的。 2.#pragma warning。允许有选择性的修改编译器的警告消息的行为。有如下用法: #pragma warning(disable:4507 34; once:4385; error:164)价于:#pragma warning(disable:4507 34) / 不显示4507和34号警告信息#pragma wa
5、rning(once:4385)/ 4385号警告信息仅报告一次#pragma warning(error:164)/ 把164号警告信息作为一个错误 #pragma warning(default:176)/ 重置编译器的176号警告行为到默认状态同时这个pragma warning也支持如下格式,其中n代表一个警告等级(1-4): #pragma warning(push) / 保存所有警告信息的现有的警告状态#pragma warning(push,n) / 保存所有警告信息的现有的警告状态,并设置全局报警级别为n#pragma warning(pop) / 例如: #pragma wa
6、rning(push) #pragma warning(disable:4705) #pragma warning(disable:4706) #pragma warning(disable:4707) #pragma warning(pop) 在这段代码后,恢复所有的警告信息(包括4705,4706和4707)。3.#pragma hdrstop。表示预编译头文件到此为止,后面的头文件不进行预编译。BCB可以预编译头文件以 加快链接的速度,但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文 件。 4.#pragma message。在标准输出设备中输出指定文本信息
7、而不结束程序运行。用法如下: #pragma message(消息文本)。当编译器遇到这条指令时就在编译输出窗口中将“消息文本”打印出来。 5.#pragma data_seg。一般用于DLL中,它能够设置程序中的初始化变量在obj文件中所在的数据段。如果未指定参数,初始化变量将放置在默认数据段.data中,有如下用法:#pragma data_seg(Shared) / 定义了数据段Shared,其中有两个变量a和bint a = 0; / 存储在数据段Shared中 int b; / 存储在数据段.bss中,因为没有初始化 #pragma data_seg() / 表示数据段Shared结
8、束,该行代码为可选的对变量进行专门的初始化是很重要的,否则编译器将把它们放在普通的未初始化数据段中而不是放在shared中。如上述的变量b其实是放在了未初始化数段.bss中。#pragma data_seg(Shared) int j = 0; / 存储在数据段Shared中 #pragma data_seg(push, stack1, Shared2) /定义数据段Shared2,并将该记录赋予别名stack1,然后放入内部编译器栈中 int l = 0; / 存储在数据段Shared2中 #pragma data_seg(pop, stack1) / 从内部编译器栈中弹出记录,直到弹出st
9、ack1,如果没有stack1,则不做任何操作 int m = 0; / 存储在数据段Shared中,如果没有上述pop段,则该变量将储在数据段Shared2中6.#pragma code_seg。它能够设置程序中的函数在obj文件中所在的代码段。如果未指定参数,函数将放置在默认代码段.text中,有如下用法:void func1() / 默认存储在代码段.text中 #pragma code_seg(.my_data1) void func2() / 存储在代码段.my_data1中 #pragma code_seg(push, r1, .my_data2) void func3() / 存
10、储在代码段.my_data2中 #pragma code_seg(pop, r1) void func4() / 存储在代码段.my_data1中 7.#pragma pack。用来改变编译器的字节对齐方式。常规用法为:#pragma pack(n) /将编译器的字节对齐方式设为n,n的取值一般为1、2、4、8、16,一般默认为8#pragma pack(show) /以警告信息的方式将当前的字节对齐方式输出#pragma pack(push) /将当前的字节对齐方式放入到内部编译器栈中#pragma pack(push,4) /将字节对齐方式4放入到内部编译器栈中,并将当前的内存对齐方式设置
11、为4#pragma pack(pop) /将内部编译器栈顶的记录弹出,并将其作为当前的内存对齐方式#pragma pack(pop,4) /将内部编译器栈顶的记录弹出,并将4作为当前的内存对齐方式#pragma pack(pop,r1) /r1为自定义的标识符,将内部编译器中的记录弹出,直到弹出r1,并将r1的值作为当前的内存对齐方式;如果r1不存在,当不做任何操作一个例子:以如下结构为例: struct char a; WORD b; DWORD c; char d; 在Windows默认结构大小: sizeof(struct) = 4+4+4+4=16;与#pragma pack(4)一样
12、若设为 #pragma pack(1), 则结构大小: sizeof(struct) = 1+2+4+1=8;若设为 #pragma pack(2), 则结构大小: sizeof(struct) = 2+2+4+2=10;在#pragma pack(1)时:空间是节省了,但访问速度降低了;有什么用处?在系统通讯中,如和硬件设备通信,和其他的操作系统进行通信时等,必须保证双方的一致性。8.#pragma comment。将一个注释记录放置到对象文件或可执行文件中。其格式为:#pragma comment( comment-type ,commentstring )。其中comment-type是
13、一个预定义的标识符,指定注释的类型,应该是compiler,exestr,lib,linker,user之一。compiler:放置编译器的版本或者名字到一个对象文件,该选项是被linker忽略的。exestr:在以后的版本将被取消。lib: 放置一个库搜索记录到对象文件中,这个类型应该与commentstring(指定Linker要搜索的lib的名称和路径)所指定的库类型一致。在对象 文件中,库的名字跟在默认搜索记录后面;linker搜索这个这个库就像你在命令行输入这个命令一样。你可以在一个源文件中设置多个库搜索记录,它们在 obj文件中出现的顺序与在源文件中出现的顺序一样。如果默认库和附加
14、库的次序是需要区别的,使用/Zl编译开关可防止默认库放到object模块中。linker:指定一个连接选项,这样就不用在命令行输入或者在开发环境中设置了。只有下面的linker选项能被传给Linker:1. /DEFAULTLIB2. /EXPORT3. /INCLUDE4. /MANIFESTDEPENDENCY5. /MERGE6. /SECTION(1)/DEFAULTLIB:library/DEFAULTLIB选项将一个library添加到LINK在解析引用时搜索的库列表。用/DEFAULTLIB指定的库在命令行上指定的库之后和obj文件中指定的默认库之前被搜索。忽略所有默认库(/NO
15、DEFAULTLIB)选项重写/DEFAULTLIB:library。如果在两者中指定了相同的library名称,忽略库(/NODEFAULTLIB:library)选项将重写/DEFAULTLIB:library。(2)/EXPORT:entryname,ordinal,NONAME,DATA使用该选项,可以从程序导出函数以便其他程序可以调用该函数,也可以导出数据。通常在DLL中定义导出。entryname是调用程序要使用的函数或数据项的名称。ordinal为导出表的索引,取值范围在1至65535;如果没有指定ordinal,则LINK将分配一个。NONAME关键字只将函数导出为序号,没有e
16、ntryname。DATA 关键字指定导出项为数据项。客户程序中的数据项必须用extern _declspec(dllimport)来声明。有三种导出定义的方法,按照建议的使用顺序依次为:1. 源代码中的_declspec(dllexport)2. .def文件中的EXPORTS语句3. LINK命令中的/EXPORT规范所有这三种方法可以用在同一个程序中。LINK在生成包含导出的程序时还要创建导入库,除非在生成过程中使用了.exp 文件。LINK使用标识符的修饰形式。编译器在创建obj文件时修饰标识符。如果entryname以其未修饰的形式指定给链接器(与其在源代码中一样),则LINK将试图
17、匹配该名称。如果无法找到唯一的匹配名称,则LINK发出错误信息。当需要将标识符指定给链接器时,请使用Dumpbin工具获取该标识符的修饰名形式。(3)/INCLUDE:symbol/INCLUDE选项通知链接器将指定的符号添加到符号表。若要指定多个符号,请在符号名称之间键入逗号(,)、分号(;)或空格。在命令行上,对每个符号需指定一次/INCLUDE:symbol。链接器通过将包含符号定义的对象添加到程序来解析symbol。该功能对于添加不会链接到程序的库对象非常有用。用该选项所指定的符号将覆盖通过/OPT:REF对该符号进行的移除操作。(4)/MANIFESTDEPENDENCY:manif
18、est_dependency/MANIFESTDEPENDENCY允许你指定位于manifest文件的段的属性。/MANIFESTDEPENDENCY信息可以通过下面两种方式传递给LINK:直接在命令行运行/MANIFESTDEPENDENCY通过#pragma comment(5)/MERGE:from=to/MERGE选项将第一个段(from)与第二个段(to)进行联合,并将联合后的段命名为to的名称。如果第二个段不存在,LINK将段(from)重命名为to的名称。/MERGE选项对于创建VxDs和重写编译器生成的段名非常有用。 (6)/SECTION:name,!DEKPRSW,ALIG
19、N=#/SECTION选项用来改变段的属性,当指定段所在的obj文件编译的时候重写段的属性集。可移植的可执行文件(PE)中的段(section)与新可执行文件(NE)中的节区(segment)或资源大致相同。段(section)中包含代码或数据。与节区(segment)不同的是,段(section)是没有大小限制的连续内存块。有些段中的代码或数据是你的程序直接定义和使用的,而有些数据段是链接器和库管理器(lib.exe)创建的,并且包含了对操作系统来说很重要的信息。/SECTION选项中的name是大小写敏感的。不要使用以下名称,因为它们与标准名称会冲突,例如,.sdata是RISC平台使用的
20、。.arch.bss.data.edata.idata.pdata.rdata.reloc.rsrc.sbss.sdata.srdata.text.xdata为段指定一个或多个属性。属性不是大小写敏感的。对于一个段,你必须将希望它具有的属性都进行指定;如果某个属性未指定,则认为是不具备这个属性。如果你未指定R,W或E,则已存在的读,写或可执行状态将不发生改变。要对某个属性取否定意义,只需要在属性前加感叹号(!)。E:可执行的R:可读取的W:可写的S:对于载入该段的镜像的所有进程是共享的D:可废弃的K:不可缓存的P:不可分页的注意K和P是表示否定含义的。PE文件中的段如果没有E,R或W属性集,则
21、该段是无效的。ALIGN=#选项让你为一个具体的段指定对齐值。user:放置一个常规注释到一个对象文件中,该选项是被linker忽略的。9.#pragma section。创建一个段。其格式为:#pragma section( section-name , attributes )section-name是必选项,用于指定段的名字。该名字不能与标准段的名字想冲突。可用/SECTION查看标准段的名称列表。attributes是可选项,用于指定段的属性。可用属性如下,多个属性间用逗号(,)隔开:read:可读取的write:可写的execute:可执行的shared:对于载入该段的镜像的所有进程是共享的nopage:不可分页的,主要用于Win32的设备驱动程序中nocache:不可缓存的,主要用于Win32的设备驱动程序中discard:可废弃的,主
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 银冶炼过程中的生产质量控制方法考核试卷
- 烘焙坊设计与布局考核试卷
- 软件项目管理工具与实践考核试卷
- 后鼻韵母教学设计
- 校园急救事故案例分析及应对策略
- 浅析外科换药
- 章小缓口腔健康环境研究
- 东南亚消费行业4月跟踪报告:印尼与泰国经济增长放缓
- 数字化银行零售业务营销转型中的金融产品创新报告2025
- 针对金融衍生品市场2025年创新风险的保险产品设计与应用报告
- 物业电路排查方案范本
- 肝动脉栓塞化疗术护理
- 警务实战基础知识
- 2025年第六届全国国家版图知识竞赛题库及答案(中小学组)
- 中国传统礼仪全课件
- 自然保护地勘界立标技术指引
- 馈线自动化-集中型馈线自动化(配电自动化)
- 《胆肠吻合技术》课件
- 围手术期患者疼痛管理课件
- 2024年度-2025年度XX村第三轮土地延包工作总结
- 《论文写作》课件 第1章 论文写作的基本概念
评论
0/150
提交评论