欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于#pragma预处理指令的那些事

程序员文章站 2022-03-02 21:06:31
...

#pragma一直是没怎么用,近日看同事写的dll用到多次所以抽时间翻一下手册,记录一下。
#pragma region name
#pragma endregion comment 可以让你折叠特定的代码块,从而使界面更加清洁,便于编辑其他代码。折叠后的代码块不会影响编译。你也可以随时展开代码块以进行编辑等操作。

在这两条指令中间输入的代码将会可折叠。在name和comment处分别可以输入代码块的名字和注释,这个功能其实用的比较多了,当代码很庞大的时候,不折叠找一个特定功能块实在是太费事。

#pragma hdrstop [( “filename” )]
#pragma hdrstop表示预编译头文件到此为止,后面的头文件不进行预编译。BCB可以预编译头文件以加快链接的速度,但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文件。
有时单元之间有依赖关系,比如单元A依赖单元B,所以单元B要先于单元A编译。你可以用#pragma startup指定编译优先级,如果使用了#pragma package(smart_init) ,BCB就会根据优先级的大小先后编译。

#pragma once 指定编译源代码文件时编译器仅包含(打开)一次文件。
使用#pragma once可以减少构建时间,因为编译器不会#include在翻译单元中的第一个文件之后打开和读取文件。这被称为多包含优化。它具有类似于#include guard的效果,它使用预处理器宏定义来防止多次包含文件内容。这也有助于防止违反一个定义规则——要求所有模板,类型,函数和对象在代码中只有一个定义。

#pragma warning 警告的相关指定
关键字:
once:只显示一次(警告/错误等)消息
default:重置编译器的警告行为到默认状态
1,2,3,4:四个警告级别
disable:禁止指定的警告信息
error:将指定的警告信息作为错误报告
例如:#pragma warning(disable:4996)表示将4996警告关闭。

#pragma data_seg(“name”)…#pragma data_seg()
用于DLL中,用于定义一个共享的,有名字的数据段。命名的数据段中的全局变量可以被多个进程共享,否则多个进程之间无法共享DLL中的全局变量。
例如:
#pragma data_seg(“flag_data”)
int count=0;
#pragma data_seg()

#pragma comment( comment-type [,“commentstring”] )该宏放置一个注释到对象文件或者可执行文件。
comment-type是一个预定义的标识符,指定注释的类型,应该是compiler,exestr,lib,linker之一。
1、compiler:放置编译器的版本或者名字到一个对象文件,该选项是被linker忽略的。
2、exestr:在以后的版本将被取消。
3、lib:放置一个库搜索记录到对象文件中,这个类型应该是和commentstring(指定你要Liner搜索的lib的名称和路径),这个库的名字放在Object文件的默认库搜索记录的后面,linker搜索这个库就像你在命令行输入这个命令一样。你可以在一个源文件中设置多个库记录,它们在object文件中的顺序和在源文件中的顺序一样。
4、linker:指定一个连接选项,这样就不用在命令行输入或者在开发环境中设置了。只有下列选项能设置linker:
/DEFAULTLIB:library
将一个 library 添加到 LINK 在解析引用时搜索的库列表。

/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]
使用该选项,可以从程序导出函数,以便其他程序可以调用该函数。entryname 是调用程序要使用的函数或数据项的名称。ordinal 在导出表中指定范围在 1 至 65,535 的索引;如果没有指定 ordinal,则 LINK 将分配一个。NONAME 关键字只将函数导出为序号,没有 entryname。

/INCLUDE:symbol
/INCLUDE 选项通知链接器将指定的符号添加到符号表。
若要指定多个符号,请在符号名称之间键入逗号 (,)、分号 (; ) 或空格。在命令行上,对每个符号指定一次 /INCLUDE:symbol。

/MANIFESTDEPENDENCY:manifest_dependency
允许您指定将放在清单文件的部分中的属性。例如:

#pragma comment(linker, "\"/manifestdependency:type='Win32' name='Test.Research.SampleAssembly' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='0000000000000000' language='*'\"")

效果如下:

<dependency>
  <dependentAssembly>
    <assemblyIdentity type='Win32' name='Test.Research.SampleAssembly' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='0000000000000000' language='*' />
  </dependentAssembly>
</dependency>

/MERGE:from=to
将from和to部分连接起来,将结果命名为to。例如/merge:.rdata=.text
如to的部分不存在,LINK以from重命名to。/ MERGE选项对于创建VxD和覆盖编译器生成的节名称非常有用。

/SECTION:name,[[!]{DEKPRSW}][,ALIGN=number]
在/ SECTION选项更改节的属性,覆盖在部分obj文件编译设置的属性。
name指的是选择节的名称,该名称是区分大小写的。请勿使用以下名称,因为它们与标准名称冲突。例如,.sdata用于RISC平台:
.arch .bss .data .edata .idata .pdata .rdata .reloc .rsrc .sbss .sdata .srdata .text .xdata
DEKPRSW为该部分指定一个或多个属性。下面列出的属性字符不区分大小写。您必须指定希望该部分具有的所有属性; 省略的属性字符会导致该属性位被关闭。如果未指定R,W或E,则现有的读取,写入或可执行状态保持不变。
要取消属性,请在其字符前加上感叹号(!)。属性字符的含义如下表所示:
字符 属性 含义
E Execute 该部分是可执行的
R Read 允许对数据读操作
W Write 允许对数据写操作
S Shared 在加载映像的所有进程*享该部分
D Discardable 将该部分标记为可废弃
K Cacheable 将该部分标记为不可缓存
P Pageable 将该部分标记为不可分页
PE文件中没有设置E,R或W的部分可能无效。
ALIGN=number,为特定部分指定对齐值,number单位是字节,必须是2的幂。

相关标签: #pragma 预处理