【转】__declspec用法详解

__declspec用法详解


  __declspec用于指定所给定类型的实例的与Microsoft相关的存储方式。其它的有关存储方式的修饰符如static与extern等是C和 C++语言的ANSI规范,而__declspec是一种扩展属性的定义。扩展属性语法简化并标准化了C和C++语言关于Microsoft的扩展。
用法:__declspec ( extended-decl-modifier )

extended-decl-modifier参数如下,可同时出现,中间使用 空格 隔开:
align (C++)
allocate
appdomain
deprecated (C++)
dllimport
dllexport
jitintrinsic
naked (C++)
noalias
noinline
noreturn
nothrow (C++)
novtable
process
property(C++)
restrict
selectany
thread
uuid(C++)
1.__declspec关键字应该出现在简单声明的前面。对于出现在 * 或 & 后面或者变量声明中标识符的前面的__declspec,编译器将忽略并且不给出警告。
2.要注意区分__declspec是修饰类型还是修饰变量:
__declspec(align(8)) struct Str b;修饰的是变量b。其它地方定义的struct Str类型的变量将不受__declspec(align(8))影响。
__declspec(align(8)) struct Str {};修饰的是struct Str类型。所有该类型的变量都受__declspec(align(8))影响。

align
格式:__declspec(align(n)) declarator
其中,n是对齐参数,其有效值是2的整数次幂(从1到8192字节),如2,4,8,16,32或64。参数declarator是要设置对齐方式的数据。
1.使用__declspec(align(n))来精确控制用户自定义数据的对齐方式。你可以在定义struct,union,class或声明变量时使用__declspec(align(n))。
2.不能为函数参数使用__declspec(align(n))。
3. 如果未使用__declspec(align(#)),编译器将根据数据大小按自然边界对齐。如4字节整数按4字节边界对齐;8字节double按8字节 边界对齐。类或结构体中的数据,将取数据本身的自然对齐方式和#pragma pack(n)设置的对齐系数中的最小值进行对齐。
4.__declspec(align(n))和#pragma pack(n)是一对兄弟,前者规定了对齐系数的最小值,后者规定了对齐系数的最大值。
5.当两者同时出现时,前者拥有更高的优先级。即,当两者同时出现且值矛盾时,后者将不起作用。
6.当变量size大于等于#pragma pack(n)指定的n,而且__declspec(align(n))指定的数值n比对应类型长度小的时候,这个__declspec(align(n))指定将不起作用。
7.当#pragma pack(n)指定的值n大于等于所有数据成员size的时候,这个值n将不起作用。

allocate
格式:__declspec(allocate("segname")) declarator
为数据指定存储的数据段。数据段名必须为以下列举中的一个:
code_seg
const_seg
data_seg
init_seg
section

appdomain
指定托管程序中的每个应用程序域都要有一份指定全局变量或静态成员变量的拷贝。

deprecated
与#pragma deprecated()的作用相同。用于指定函数的某个重载形式是不推荐的。当在程序中调用了被deprecated修饰的函数时,编译器将给出C4996警告,并且可以指定具体的警告信息。该警告信息可以来源于定义的宏。
例如:
// compile with: /W3
#define MY_TEXT "function is deprecated"
void func1(void) {}
__declspec(deprecated) void func1(int) {}
__declspec(deprecated("** this is a deprecated function **")) void func2(int) {}
__declspec(deprecated(MY_TEXT)) void func3(int) {}

int main() {
   func1();
   func1(1);   // C4996,警告信息:warning C4996: 'func1': was declared deprecated
   func2(1);   // C4996,警告信息:warning C4996: 'func2': ** this is a deprecated function **
   func3(1);   // C4996,警告信息:warning C4996: 'func3': function is deprecated
}

dllimport,dllexport
格式:
__declspec( dllimport ) declarator
__declspec( dllexport ) declarator
分别用来从dll导入函数,数据,或对象以及从dll中导出函数,数据,或对象。相当于定义了dll的接口,为它的客户exe或dll定义可使用的函数,数据,或对象。
将函数声明成dllexport就可以免去定义模块定义(.DEF)文件。
dllexport代替了__export关键字。
被声明为dllexport的C++函数导出时的函数名将会按照C++规则经过处理。如果要求不按照C++规则进行名字处理,请使用.def文件或使用extern "C"。

jitintrinsic
格式:__declspec(jitintrinsic)
用于标记一个函数或元素是64位通用语言运行时(CLR)。主要用于Microsoft提供的某些库中。
使用jitintrinsic会在函数签名中加入MODOPT(IsJitIntrinsic)。

naked
格式:__declspec(naked) declarator
此关键字仅用于x86系统,多用于虚拟设备驱动。此关键字可以使编译器在生成代码时不包含任何注释或标记。仅可以对函数的定义使用,不能用于数据声明、定义,或者函数的声明。

noalias
仅适用于函数,它指出该函数是半纯粹的函数。半纯粹的函数是指仅引用或修改局部变量、参数和第一层间接参数。它是对编译器的一个承诺,如果该函数引用全局变量或第二层间接指针参数,则编译器会生成中断应用程序的代码。

restrict
格式:__declspec(restrict) return_type f();
仅 适用于返回指针的函数声明或定义,如,CRT的malloc函数:__declspec(restrict) void *malloc(size_t size);它告诉编译器该函数返回的指针不会与任何其它的指针混淆。它为编译器提供执行编译器优化的更多信息。对于编译器来说,最大的困难之一是确定哪 些指针会与其它指针混淆,而使用这些信息对编译器很有帮助。有必要指出,这是对编译器的一个承诺,编译器并不对其进行验证。如果您的程序不恰当地使用 __declspec(restrict),则该程序的行为会不正确。

noinline
因为在类定义中定义的成员函数默认都是inline的,__declspec(naked)用于显式指定类中的某个函数不需要inline(内联)。如果一个函数很小而且对系统性能影响不大,有必要将其声明为非内敛的。例如,用于处理错误情况的函数。

noreturn
一个函数被__declspec(noreturn)所修饰,那么它的含义是告诉编译器,这个函数不会返回,其结果是让编译器知道被修饰为__declspec(noreturn)的函数之后的代码不可到达。
如果编译器发现一个函数有无返回值的代码分支,编译器将会报C4715警告,或者C2202错误信息。如果这个代码分支是因为函数不会返回从而无法到达的话,可以使用约定__declspec(noreturn)来避免上述警告或者错误。
将一个期望返回的函数约定为__declspec(noreturn)将导致未定义的行为。
在下面的这个例子中,main函数没有从else分支返回,所以约定函数fatal为__declspec(noreturn)来避免编译或警告信息。
__declspec(noreturn) extern void fatal () {}
int main() {
if(1)
   return 1;
else if(0)
   return 0;
else
   fatal();
}

nothrow:
格式:return-type __declspec(nothrow) [call-convention] function-name ([argument-list])
可用于函数声明。告诉编译器被声明的函数以及函数内部调用的其它函数都不会抛出异常。

novtable
可用于任何类声明中,但最好只用于纯接口类,即类本身从不实例化。此关键字的声明将阻止编译器对构造和析构函数的vfptr的初始化。可优化编译后代码大小。
如果试图实例化一个用__declspec(novtable)声明的类然后访问类中成员,则会在运行时产生访问错误(access violation,即AV)。

process
表示你的托管应用程序进程应该拥有一份指定全局变量,静态成员变量,或所有应用程序域 共享的静态本地变量的拷贝。在使用/clr:pure进行编译时,应该使用__declspec(process),因为使用/clr:pure进行编译 时,在默认情况下,每个应用程序域拥有一份全局和静态变量的拷贝。在使用/clr进行编译时,不必使用__declspec(process),因为使用 /clr进行编译时,在默认情况下,每个进程有一份全局和静态变量的拷贝。
只有全局变量,静态成员变量,或本地类型的本地静态变量可以用__declspec(process)修饰。
在使用/clr:pure进行编译时,被声明为__declspec(process)的变量同时也应该声明为const类型。
如果想每个应用程序域拥有一份全局变量的拷贝时,请使用appdomain。

property
格式:
__declspec( property( get=get_func_name ) ) declarator
__declspec( property( put=put_func_name ) ) declarator
__declspec( property( get=get_func_name, put=put_func_name ) ) declarator
该 属性可用于类或结构定义中的非静态“虚数据成员”。实际上就是做了一个映射,把你的方法映射成属性,以供访问。get和put就是属性访问的权限,一个是 读的权限,一个是写的权限。当编译器看到被property修饰的数据成员出现在成员选择符("." 或 "->")的右边的时候,它将把该操作转换成get或put方法。该修饰符也可用于类或结构定义中的空数组。
用法如下:
struct S {
   int i;
   void putprop(int j) {
      i = j;
   }
   int getprop() {
      return i;
   }
   __declspec(property(get = getprop, put = putprop)) int the_prop;
};

int main() {
   S s;
   s.the_prop = 5;
   return s.the_prop;
}

selectany
格式:__declspec(selectany) declarator
在 MFC,ATL的源代码中充斥着__declspec(selectany)的声明。selectany可以让我们在.h文件中初始化一个全局变量而不是 只能放在.cpp中。比如有一个类,其中有一个静态变量,那么我们可以在.h中通过类似__declspec(selectany) type class::variable = value;这样的代码来初始化这个全局变量。既是该.h被多次include,链接器也会为我们剔除多重定义的错误。对于template的编程会有很 多便利。
用法如下:

__declspec(selectany) int x1=1; //正确,x1被初始化,并且对外部可见

const __declspec(selectany) int x2 =2; //错误,在C++中,默认情况下const为static;但在C中是正确的,其默认情况下const不为static

extern const __declspec(selectany) int x3=3; //正确,x3是extern const,对外部可见

extern const int x4;
const __declspec(selectany) int x4=4; //正确,x4是extern const,对外部可见

extern __declspec(selectany) int x5; //错误,x5未初始化,不能用__declspec(selectany)修饰

class X {
public:
X(int i){i++;};
int i;
};

__declspec(selectany) X x(1); //正确,全局对象的动态初始化

thread
格式:__declspec(thread) declarator
声明declarator为线程局部变量并具有线程存储时限,以便链接器安排在创建线程时自动分配的存储。
线程局部存储(TLS)是一种机制,在多线程运行环境中,每个线程分配自己的局部数据。在标准多线程程序中,数据是在多个线程间共享的,而TLS是一种为每个线程分配自己局部数据的机制。
该属性只能用于数据或不含成员函数的类的声明和定义,不能用于函数的声明和定义。
该属性的使用可能会影响DLL的延迟载入。
该属性只能用于静态数据,包括全局数据对象(static和extern),局部静态对象,类的静态数据成员;不能用于自动数据对象。
该属性必须同时用于数据的声明和定义,不管它的声明和定义是在一个文件还是多个文件。
__declspec(thread)不能用作类型修饰符。
如果在类声明的同时没有定义对象,则__declspec(thread)将被忽略,例如:

// compile with: /LD
__declspec(thread) class X
{
public:
   int I;
} x;   //x是线程对象
X y;   //y不是线程对象

下面两个例子从语义上来说是相同的:

__declspec(thread) class B {
public:
   int data;
} BObject;   //BObject是线程对象

class B2 {
public:
   int data;
};
__declspec(thread) B2 BObject2;   // BObject2是线程对象

uuid
格式:__declspec( uuid("ComObjectGUID") ) declarator
将具有唯一标识符号的已注册内容声明为一个变量,可使用__uuidof()调用。
用法如下:
struct __declspec(uuid("00000000-0000-0000-c000-000000000046")) IUnknown;
struct __declspec(uuid("{00020400-0000-0000-c000-000000000046}")) IDispatch;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436187.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EBOOT跳转到NK的过程

先做个说明:我的平台环境是:CE5.0(S3C2450)。 我的config.bib定义的镜像起始地址为0x8c20 0000(虚拟地址), EBoot将镜像下载到以0x8c20 0000为起始地址的RAM中, 但实际上OS跳转的地址却是0x8c20 1000, 也就是说, 传递到Lauch函数的…

thinkphp index.php隐藏,thinkphp5怎么隐藏index.php入口文件?

隐藏方法:1、打开apache的http.conf配置文件,开启mod_rewrite.so模块;2、AllowOverride None项中将None改为All;3、修改“.htaccess”的配置内容,将原代码替换为官方手册提供的代码。thinkphp现在的php主流框架之一&am…

【转】extern “C“和__declspec(dllexport)以及__declspec(dllimport) 和def的简单解析

转自:https://blog.csdn.net/xupan_jsj/article/details/9028759 前面的extern "C" __declspec(dllexport) __declspec(dllimport)都是用于函数或者变量,甚至类的声明的(可以把extern "C"放在class的前面,…

JAGUARSDN1网络的开机自动启动 禁用,WIFI模块的启动关闭控制

先确认下系统中有没有加载NDISPWR.DLL,如果没有的话,把这个组件加上 WIFI在默认情况下,是开机自动打开的,如果要开机禁用,在HKEY_LOCAL_MACHINE/Comm/NdisPower创建一个键值 name 4 name是你用的WIFI的名字 如果想…

高考临考突发情况应急预案大全

临考感冒看卷头痛如何应对 高考应急预案助考生 明天,全省49万余考生就将走进高考考场,考生顺利迎考是全社会的心愿,可种种意外总有可能出现在考生面前。高考过程中遇到意外情况如何处理?昨天,本报记者约请了多位考试专…

php病毒图片后缀名,脚本图片类后门病毒的完美使用方法

前两天,看了一篇《脚本注入图片新方法》的文章,相信很多人都通过这篇文章了解了如何在图片中加入脚本,以及如何在正常的asp(或php)文件中通过include函数使图片中的脚本产生效用。但是,这种方法的问题又随之而来了:有人…

WPF指南之XAML概述

[转]WPF指南之XAML概述 周日, 05/04/2008 - 23:26 — robot 出处: it168要赢得世界,必须在恰当的时间做出恰当的事。这一点,微软做到了。历经微软DOS,Win 31, Win95, Win 98, Win 2k, WinXP, 一路走来,一次比一次热闹,…

如何修改wince的网络配置

如何修改wince的网络配置呢? 首先,必须知道网卡驱动名字。在s3c2410上,名字叫“CS8900”,用工具连接上wince查看他的注册表。你将可以得到下面的东西。 [HKEY_LOCAL_MACHINE/Comm/CS8900] "DisplayName""CS8900&qu…

【转】extern “C“以及__declspec(dllexport) 讲解和def文件dll导出方法

转自:https://blog.csdn.net/qing666888/article/details/41135245 一,__ declspec(dllexport): 将一个函数声名为导出函数,就是说这个函数要被其他程序调用,即作为DLL的一个对外函数接口。通常…

php源码查找替换,php 替换模板中的 PHP源码标签字符方法

//替换php代码function RepPhpAspJspcode($string){global $public_r;if(!$public_r[candocode]){//$stringstr_replace("<?xml ","[!--ecms.xml--]",$string);$stringstr_replace("$stringstr_replace("\\>","\\>",$s…

【转】DICOM医学图像处理:浅析SWF、MWL、SPS、MPPS

转自&#xff1a;https://blog.csdn.net/zssureqh/article/details/40151107 背景&#xff1a; 最近重新花时间阅读了DICOM标准&#xff0c;顺带着看了一下HL7标准和IHE&#xff0c;对标题中提到的SWF、MWL、SPS和MPPS有了更进一步的认识&#xff0c;现将自己的理解整理出来&a…

Parallel Extensions CTP第二版发布

Parallel Extensions CTP第二版发布 LazyBee 2008年6月微软Parallel Extensions项目组发布了Parallel Extendsions CTP的第二个版本。这个版本主要包含以下组件&#xff1a; 1 任务并行库TPL(Task Parallel Library): 提供命令的方式将面向数据的操作以及轻量级的任务自动的运行…

wince中的背光灯控制

要控制背光灯就必须知道相关设置&#xff0c;以下是wince中背光灯的设置。在BL_ReadRegistry函数中被读取。 [HKEY_CURRENT_USER/ControlPanel/BackLight] "ACTimeout"dword:0000012c "UseExt"dword:00000001 "UseBattery"dword:00000001 …

Php点击更换封面,JavaScript_js实现点击图片改变页面背景图的方法,本文实例讲述了js实现点击图 - phpStudy...

js实现点击图片改变页面背景图的方法本文实例讲述了js实现点击图片改变页面背景图的方法。分享给大家供大家参考。具体实现方法如下&#xff1a;点击图片即改变页面的背景图片希望本文所述对大家的javascript程序设计有所帮助。相关阅读:C语言编程中统计输入的行数以及单词个数…

VistaDB 数据库,.NET的新选择

VistaDB 3.3 fully managed embedded database engine runs Nothing but .Net! Designed and built as a 100% managed code database engine. Now with TSQL Procs! 商业版&#xff0c;提供ADO.NET 2.0 的Provider。商业版。但是有 Express 版&#xff0c;可应用于非商业环境。…

wince中重启网卡

WCHAR Name[]_T("CS89001/0"); HANDLE m_hFileHandle CreateFile(_T("NDS0:"), 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) INVALID_HANDLE_VALUE); if( m_hFileHandle INVALID_HANDLE_VALUE ) { //获得网卡名时打开设备错误 …

【转】DICOM的常用Tag分类和说明

转自&#xff1a;https://blog.csdn.net/inter_peng/article/details/46513847 1. 前言&#xff1a; 基于DICOM3.0标准的医学图像中&#xff0c;每一张图像中都携带着许多的信息&#xff0c;这些信息主要可以分为Patient, Study, Series和Image四类。每一个DICOM Tag都…

matlab电压稳定极限,电力系统电压稳定性的Matlab建模分析

Matlab软件作为一个编程效率高、程序设计灵活、图形功能强的工程实用的分析软件,在电力系统的仿真分析及相关计算中得以广泛应用,特别是其中的Simulink工具箱可以实现电力系统的模型建立及动态仿真[1].但是在实际应用中,特别是针对电力系统的动态过程分析,Simulink存在以下2个问…

串口通讯基础及S3C2410 UART控制器

数据通信的基本方式可分为并行通信与串行通信两种&#xff1a; 并行通信&#xff1a;是指利用多条数据传输线将一个资料的各位同时传送。它的特点是传输速度快&#xff0c;适用于短距离通信&#xff0c;但要求通讯速率较高的应用场合。 串行通信&#xff1a;是指利用一条传输线…

几个实用的Servlet应用例子-入门、cookie、session及上传文件

1Servlet可以被认为是服务端的applet&#xff0c;它被WEB服务器加载和执行&#xff0c;前端可以显示页面和获得页面数据&#xff0c;后台可以操纵数据库&#xff0c;能完成JavaBean的很多功能。在这里我较为详细的说说Servlet在Cookie&#xff0c;Session和上传文件上的应用&am…