#pragma 的使用

我们经常用到的是#pragma comment(lib,"*.lib")这类的。
#pragma comment(lib,“Ws2_32.lib”)表示链接Ws2_32.lib这个库。
和在工程设置里写上链入Ws2_32.lib的效果一样,不过这种方法写的
程序别人在使用你的代码的时候就不用再设置工程settings了

尽管 C 和 C++ 都已经有标准,但是几乎每个编译器 (广义,包含连接器等) 扩展一些 C/C++ 关键字。

合理地应用这些关键字,有时候能使我们的工作非常方便。下面随便说说 Visual C++ 中 #pragma

指示符的使用。

一、用#pragma导出DLL函数
传统的到出 DLL 函数的方法是使用模块定义文件 (.def),Visual C++ 提供了更简洁方便的方法,

那就是“__declspec()”关键字后面跟“dllexport”,告诉连接去要导出这个函数,例如:

__declspec(dllexport) int __stdcall MyExportFunction(int iTest);

把“__declspec(dllexport)”放在函数声明的最前面,连接生成的 DLL 就会导出函数

“_MyExportFunction@4”。

上面的导出函数的名称也许不是我的希望的,我们希望导出的是原版的“MyExportFunction”。

还好,VC 提供了一个预处理指示符“#pragma”来指定连接选项 (不仅仅是这一个功能,还有很多指示功能) ,

如下:

#pragma comment(linker,"/EXPORT:MyExportFunction=_MyExportFunction@4")

这下就天如人愿了:)。如果你想指定导出的顺序,或者只将函数导出为序号,没有 Entryname,

这个预处理指示符 (确切地说是连接器) 都能够实现,看看 MSDN 的语法说明:

/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]

@ordinal 指定顺序;NONAME 指定只将函数导出为序号;DATA 关键字指定导出项为数据项。

二、指示文件只包含一次

在头文件中,一般在整个工程中我们只要包含一次就够了,但是如果我在多个 .c/.cpp 文件中都要包

含着个头文件,比如 Windows.h,那很多声明等等岂不是有两次了?解决这个问题的传统的方法是在头文件

开始出用

#define 定义一个宏,比如 Windows.h 中:

  #ifndef _WINDOWS_#define _WINDOWS_P>    然后在文件结为加上 #endif,这样就可以避免被包含多次。但是这样的后果是代码的可读性较差

(个人观点),VC 给我们提供了另外一个途径,那就是在文件的前面加上:#pragma once 是不是很方便?

三、使警告无效 有时候我们不得不对变量进行强制转换,由此引来编译器的一番警告,特别是 C++ 中

,类型检查相对于 C 更为严格。这虽然不影响什么,但是看起来多不爽——我是故意要这样的,

你警告什么!:)这时候你看到警告类型,

比如“warning C4311: “类型转换” : 从“HHOOK”到“BOOL”的指针截断”,在前面加上:

#pragma warning(disable: 4311) 编译器就没话说了:)。

四、指定连接要使用的库 比如我们连接的时候用到了 WSock32.lib,你当然可以

不辞辛苦地把它加入到你的工程中。但是我觉得更方便的方法是使用 #pragma 指示符,指定要连接的库:

#pragma comment(lib, “WSock32.lib”)五、显示编译消息 没多少用处,举个例子吧:

#ifdef _DEBUG#pragma message

(“编译连接为调试模式…”)#endif // _DEBUG

在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示

编译器完成一些特定的动作。#pragma
指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有

的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。
其格式一般为: #Pragma Para
其中Para 为参数,下面来看一些常用的参数。

(1)message 参数。 Message 参数是我最喜欢的一个参数,它能够在编译信息输出窗
口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为:
#Pragma message(“消息文本”)
当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。
当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设

置这些宏,此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源

代码的什么地方定义了

_X86这个宏可以用下面的方法
#ifdef _X86
#Pragma message(“X86 macro activated!”)
#endif
当我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示“

X86 macro activated!”。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了

(2)另一个使用得比较多的pragma参数是code_seg。格式如:
#pragma code_seg( [“section-name”[,“section-class”] ] )
它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。

(3)#pragma once (比较常用)
只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在VC6中就已经有了,

但是考虑到兼容性并没有太多的使用它。

(4)#pragma hdrstop表示预编译头文件到此为止,后面的头文件不进行预编译。BCB可以预编译头文件以加

快链接的速度,但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文件。
有时单元之间有依赖关系,比如单元A依赖单元B,所以单元B要先于单元A编译。你可以用

#pragma startup指定编译优先级,如果使用了#pragma package(smart_init) ,BCB就会根据优先级的

大小先后编译。

(5)#pragma resource ".dfm"表示把.dfm文件中的资源加入工程。*.dfm中包括窗体
外观的定义。

(6)#pragma warning( disable : 4507 34; once : 4385; error : 164 )
等价于:
#pragma warning(disable:4507 34) // 不显示4507和34号警告信息
#pragma warning(once:4385) // 4385号警告信息仅报告一次
#pragma warning(error:164) // 把164号警告信息作为一个错误。
同时这个pragma warning 也支持如下格式:
#pragma warning( push [ ,n ] )
#pragma warning( pop )
这里n代表一个警告等级(1—4)。
#pragma warning( push )保存所有警告信息的现有的警告状态。
#pragma warning( push, n)保存所有警告信息的现有的警告状态,并且把全局警告
等级设定为n。
#pragma warning( pop )向栈中弹出最后一个警告信息,在入栈和出栈之间所作的
一切改动取消。例如:
#pragma warning( push )
#pragma warning( disable : 4705 )
#pragma warning( disable : 4706 )
#pragma warning( disable : 4707 )
//…
#pragma warning( pop )
在这段代码的最后,重新保存所有的警告信息(包括4705,4706和4707)。
(7)pragma comment(…)
该指令将一个注释记录放入一个对象文件或可执行文件中。
常用的lib关键字,可以帮我们连入一个库文件。

#pragma comment( comment-type [,“commentstring”] )

comment-type是一个预定义的标识符,指定注释的类型,应该是compiler,exestr,lib,linker之一。
commentstring是一个提供为comment-type提供附加信息的字符串,
Remarks:
1、compiler:放置编译器的版本或者名字到一个对象文件,该选项是被linker忽略的。
2、exestr:在以后的版本将被取消。
3、lib:放置一个库搜索记录到对象文件中,这个类型应该是和commentstring(指定你要Liner搜索的lib的名称和路径)
这个库的名字放在Object文件的默认库搜索记录的后面,linker搜索这个这个库就像你在命令行输入这个命令一样。你可以
在一个源文件中设置多个库记录,它们在object文件中的顺序和在源文件中的顺序一样。如果默认库和附加库的次序是需要
区别的,使用Z编译开关是防止默认库放到object模块。
4、linker:指定一个连接选项,这样就不用在命令行输入或者在开发环境中设置了。
只有下面的linker选项能被传给Linker.
/DEFAULTLIB

/EXPORT

/INCLUDE

/MANIFESTDEPENDENCY

/MERGE

/SECTION

(1)/DEFAULTLIB:library

/DEFAULTLIB 选项将一个 library 添加到 LINK 在解析引用时搜索的库列表。用 /DEFAULTLIB 指定的库在命令行上指定的库之后和 .obj 文件中指定的默认库之前被搜索。
忽略所有默认库 (/NODEFAULTLIB) 选项重写 /DEFAULTLIB:library。如果在两者中指定了相同的 library 名称,忽略库 (/NODEFAULTLIB:library) 选项将重写 /DEFAULTLIB:library。

(2)/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]

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

DATA 关键字指定导出项为数据项。客户程序中的数据项必须用 extern __declspec(dllimport) 来声明。
有三种导出定义的方法,按照建议的使用顺序依次为:

源代码中的 __declspec(dllexport)

.def 文件中的 EXPORTS 语句

LINK 命令中的 /EXPORT 规范

所有这三种方法可以用在同一个程序中。LINK 在生成包含导出的程序时还创建导入库,除非生成中使用了 .exp 文件。
LINK 使用标识符的修饰形式。编译器在创建 .obj 文件时修饰标识符。如果 entryname 以其未修饰的形式指定给链接器(与其在源代码中一样),则 LINK 将试图匹配该名称。如果无法找到唯一的匹配名称,则 LINK 发出错误信息。当需要将标识符指定给链接器时,请使用 Dumpbin 工具获取该标识符的修饰名形式。

(3)/INCLUDE:symbol
/INCLUDE 选项通知链接器将指定的符号添加到符号表。

若要指定多个符号,请在符号名称之间键入逗号 (,)、分号 (? 或空格。在命令行上,对每个符号指定一次 /INCLUDE:symbol。
链接器通过将包含符号定义的对象添加到程序来解析 symbol。该功能对于添包含不会链接到程序的库对象非常有用。用该选项指定符号将通过 /OPT:REF 重写该符号的移除。

转自 https://www.cnblogs.com/guoxiaoqian/p/3984972.html

pragma comment的使用相关推荐

  1. [转]pragma comment的使用

    pragma comment的使用 该宏放置一个注释到对象文件或者可执行文件. #pragma comment( comment-type [,"commentstring"] ) ...

  2. [转]#pragma once和#pragma comment

    编程经常碰到,理解的总不是很透彻,在这里查阅资料总结一下! 在编写程序的时候,我们常用到#pragma指令来设定编译器的状态或者是指示编译器完成一些特定的动作. #pragma once : 这是一个 ...

  3. VS2008下利用#pragma comment屏蔽VC/VS生成的exe程序的CMD窗口

    2016-6-1日注:此种方法并不适用于VS2012,在VS2012中屏蔽CMD的方法可以见博文:VS2012及VS系列怎样屏蔽CMD窗口~_昊虹图像算法-CSDN博客_vs 不打开cmd 有时候我们 ...

  4. 屏蔽控制台应用程序的窗口#pragma comment(linker, /subsystem:windows /ENTRY:mainCRTStartup)...

    众所周知,控制台应用程序一般都会显示一个控制台窗口(虚拟DOS窗口),但很多时候控制台程序的执行逻辑根本不需要与用户进行交互,所以显示这个难看的窗口纯属多余,那么如何将它屏蔽掉呢?下面我向大家介绍一种 ...

  5. C++ #pragma comment语法(预处理指令)

    #pragma comment的使用方法 pragma预处理指令详解 后更

  6. pragma comment的使用 pragma预处理指令详解

    pragma comment的使用 pragma预处理指令详解 #pragma comment( comment-type [,"commentstring"] ) 该宏放置一个注 ...

  7. #pragma comment(linker,/SECTION:shared,RWS)

    Windows在一个Win32程序的地址空间周围筑了一道墙.通常,一个程序的地址空间中的数据是私有的,对别的程序而言是不可见的.但是执行多个执行实体表示了程序的所有执行实体之间共享数据是毫无问题的.当 ...

  8. #pragma comment和#pragma 预处理指令详解

    该宏放置一个注释到对象文件或者可执行文件. 例如,#pragma   comment(lib,"Ws2_32.lib")表示链接Ws2_32.lib这个库. 和在工程设置里写上链入 ...

  9. 预处理指令pragma常见用法集锦(#pragma once、#pragma comment和#pragma warning)

    #pragma once: 这是一个比较常用的指令,只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,避免文件被重复包含. ********************************* ...

  10. QT error: LNK2019: 无法解析的外部符号 __imp__SendMessageW@ 类型的错误 以及 pragma comment 的作用(用法)

    使用QT Creator 开发一个通讯项目时候,需要使用windows系统函数,比如: #include <windows.h> #include <WinUser.h> .. ...

最新文章

  1. 微软 Windows 10 物联网版系统 IoT 介绍 树莓派2 可以装一下
  2. 错误C4146的解决方法
  3. 三种方法实现Linux系统调用方法分享
  4. 研究:低智商男人易出轨
  5. boost::ptr_set相关的测试程序
  6. 网易视频云分享:如何搭建视频转码集群
  7. AbstractQueuedSynchronizer理解之三(Semaphore)
  8. response对象设置返回状态_postman 设置全局变量
  9. VS2008 正式版 下载+ KEY 注册码
  10. 项目部署到服务器后字符编码,将UTF-8编码的数据发布到服务器会丢失某些字符...
  11. PDMS二次开发(十二)——螺栓材料统计功能一批bug修复之后再次用sample项目进行验证
  12. 2019计算机世界语言排名,2019程序语言排行_2019 年 8 月编程语言排行榜
  13. Java学习笔记22:并发(2)
  14. 初学C语言1--C语言用什么软件编写
  15. 计算机专业课程计划,计算机专业课程表(教学计划)
  16. 一个SAP程序员的2020年度总结:未知生,焉知死
  17. 【数字经济】概念、技术、实践:中国 500强泰康集团背后的数据驱动
  18. shim是应该抛异常还是应该fail silently?
  19. 物联网发展从开始到成型,需要经过哪几个阶段?
  20. 4亿玩家巅峰之作 《捕鱼达人3》全球震撼发布!

热门文章

  1. relativePath
  2. python爬duitang的摄影类图片
  3. Python的繁体简体转换
  4. 我国学生被美深泉学院录取 每周20小时放牛种草
  5. resample按时间聚合
  6. 海明码的编码和校验方法
  7. 教你一步一步用VPS
  8. Java Duration类和Period类
  9. Hive之——Hive2.0函数大全
  10. iTunes 10 选择自定义IPSW