#pragma的用法
在所有的预处理指令中,#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 pack(1) 作用
主
要用来设置结构定义的字节对齐方式,比如是单字节对齐,双字节对齐等,比如如果是双字节对齐,那么结构的成员变量的地址必须是2的整数倍,这就造成了字节
补齐,但是提高了访问速度。单字节呢,就是没有补齐,成员变量的地址是连续的,其他依次类推,通常是4,8等。通常用于网络传输数据,特别是传输整个结构
时,必须采取单字节对齐,这样才可以直接把结构地址,以及结构长度,作为Send的参数发送整个结构,否则只能依次发送结构的成员,要不然会出现结构解释
的差异。
另外,在Project->Setting->C/C++->Code Generation->Struct member alignment中可以设置结构的对齐方式。
传输结构时和pack无关,只要Recv端定义的结构和Send方一样就没问题了。
pack多用于Hook程序,比如Hook Api技术,因为需要硬编码,所以必须将结构
压缩,将内容补齐!
比如:
ASM_STRUCT{
BYTE bJmp;
DWORD dwDes;
}a;
如果不用Pack时,编译为:
a.bJmp = 0xEB; // jmp的编码
a.dwDes = 0x00410123; // jmp 0x00410123
不用pack的话,内存内容为 0xEB XX XX XX 23 01 41 00 // 共8BYTE
其中XX为不定值,用pack后 0xEB 23 01 41 00 // 共5BYTE
这样,在Hook时运行这些指令,就必须用#parama pack(1) // 1 BYTE方式对齐。
如果直接把结构地址,以及结构长度,作为Send的参数发送整个结构,难道不需要pack吗?请教verybigbug()兄
不需要。
send(struct, sizeof(struct));就可以了,如果两个程序都没有pack的话,
相同的结构体在接收数据时就没有问题。必须保证两边的pack都是一样才行。
我在写socket的程序(SDK方式)时送结构就从来不用pack的。
只在写Hook Api时才用pack(1)。
#pragma comment(lib, "ws2_32") 是什么意思 ???
.就相当于你将ws2_32.lib包含到工程中去。这样你就可以使用DLL接口函数了
#pragma data_seg 是什么意思??
用#pragma data_seg建立一个新的数据段并定义共享数据,其具体格式为:
#pragma data_seg ("shareddata")
HWND sharedwnd="NULL";//共享数据
#pragma data_seg() // 再windows 核心编程思想中有很多地方用到。
#pragma的用法的更多相关文章
- #pragma once用法总结
1.#pragmaonce这个宏有什么作用? 为了避免同一个头文件被包含(include)多次,C/C++中有两种宏实现方式:一种是#ifndef方式:另一种是#pragma once方式. 在能够支 ...
- 【转】#pragma的用法
在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的 ...
- #pragma 的用法
它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征.依据定义,编译指示是机 ...
- #pragma pack()用法详解
博客转载自:http://blog.csdn.net/lime1991/article/details/44536343 1.什么是对齐?为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从 ...
- 进程共享变量#pragma data_seg用法
#pragma data_seg介绍 用#pragma data_seg建立一个新的数据段并定义共享数据,其具体格式为: #pragma data_seg ("shareddata" ...
- 汇总#pragma用法
这几天忙着去复习了,但是心理总是不踏实,不到实验室里就觉得一天的生活变了个样,现在还是晚上来这里“搞起”吧,白天还是在复习准备考试.因为要开始学习freescale,准备明年的比赛了,觉得是时候开始搞 ...
- [C++] 头文件中的#ifndef,#define,#endif以及#pragma用法
想必很多人都看过“头文件中用到的 #ifndef/#define/#endif 来防止该头文件被重复引用”.但是是否能理解“被重复引用”是什么意思?头文件被重复引用了,会产生什么后果?是不是所有的头文 ...
- pragma comment
pragma指令简介 在编写程序的时候,我们经常要用到#pragma指令来设定编译器的状态或者是指示编译器完成一些特定的动作. 下面介绍了一下该指令的一些常用参数,希望对大家有所帮助! 一. mess ...
- c/c++头文件中#ifndef/#define/#endif的用法
想必很多人都看过“头文件中用到的 #ifndef/#define/#endif 来防止该头文件被重复引用”.但是是否能理解“被重复引用”是什么意思?头文件被重复引用了,会产生什么后果?是不是所有的头文 ...
随机推荐
- Windows下bat命令
一.简单批处理内部命令简介 1.Echo 命令 打开回显或关闭请求回显功能,或显示消息.如果没有任何参数,echo 命令将显示当前回显设置. 语法 echo [{on│off}] [mess ...
- Java引用数据类型
值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参 数的值.引用传递:也称为传地址.方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应 ...
- C语言 格式说明符
整数 lL代表long %#0 和%#x 可打印出八进制和十六进制前缀 short int long long long 无符号 八进制 %ho %o %Lo %LLo 十进制 %hu %u %Lu ...
- cad2007 钢筋符号显示为问号
如题:cad2007 钢筋符号显示为问号 解决办法:下载Tssdeng,解压(Tssdeng.rar) 把下载到的cad大字体Tssdeng.shx文件放到autoCAD2007安装目录C:\Prog ...
- eclipse 打开文件目录
用简单的配置方式 eclipse打开当前文件所在文件夹的插件 Run-->External Tools-->External Tools Configurations... new 一个 ...
- android 传感器使用 Compass指南针的实现功能
以下是指南针通过方向传感器而旋转实现. CompassDemo.java: package com.example.activity; import android.app.Activity; imp ...
- 数据库CRUD操作
CRUD操作: C:create 增加数据: insert into 表名 values('N001','汉族') 普通 insert into 表名 values('','','') 如果有自增长列 ...
- Dynamics CRM 2013 初体验(1):系统的安装
最近收到Microsoft的Dynamics CRM 2013 beta测试邀请,终于让我掀开了它神秘的面纱.自从去年的Dynamics CRM 2012 December补丁包发布后,系统就添加了很 ...
- jeecms 2012 源码分析(2) 前台栏目页静态化分析
还是要说到web.xml文件 <welcome-file-list> <welcome-file>index.html</welcome-file> <wel ...
- SurfaceView 和 View 区别
android.view.View 和 android.view.SurfaceView SurfaceView 是从 View 基类中派生出来的显示类,直接子类有 GLSurfaceView和Vid ...