c++ 中__declspec 的用法详解

2020-01-06 15:59:00于丽

e.g 常规方式dll中


class ___declspec(dllexport) 
testdll{ 
testdll(){}; 
~testdll(){};
};

调用客户端中声明
#import comment(lib, "**.lib)
class ___declspec(dllimportt) 
testdll{ 
testdll(){}; 
~testdll(){};
}; 

e.g 模板类:dll中


template<class t>
class test{
test(){};
~test(){};
}
调用客户端中声明
int main()
{
test< int > b;
return 0;
} 

5. jitintrinsic

用__declspec(jitintrinsic)标记一个函数或元素为64位公共语言运行时。具体用法未见到。

6. __declspec( naked ) 

对于没有用naked声明的函数一般编译器都会产生保存现场(进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器 ——prolog)和清除现场(退出函数时则产生代码恢复这些寄存器的内容——epilog) 代码,而对于用naked声明的函数一般不会产生这些代码,这个属性对于写设备驱动程序非常有用,我们自己可以写这样一个过程,它仅支持x86 。naked只对函数有效,而对类型定义无效。对于一个标志了naked的函数不能产生一个内联函数即时使用了__forceinline 关键字。

e.g


__declspec ( naked ) func()
{
int i;
int j;
__asm /* prolog */
{
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
}
/* Function body */
__asm /* epilog */
{
mov esp, ebp
pop ebp
ret
}
} 

7. restrict 和 noalias

__declspec(restrict) 和 __declspec(noalias)用于提高程序性能,优化程序。这两个关键字都仅用于函数,restrict针对于函数返回指针,restrict 说明函数返回值没有被别名化,返回的指针是唯一的,没有被别的函数指针别名花,也就是说返回指针还没有被用过是唯一的。编译器一般会去检查指针是否可用和 是否被别名化,是否已经在使用,使用了这个关键字,编译器就不在去检查这些信息了。noalias 意味着函数调用不能修改或引用可见的全局状态并且仅仅修改指针参数直接指向的内存。如果一个函数指定了noalias关键字,优化器认为除参数自生之外, 仅仅参数指针第一级间接是被引用或修改在函数内部。可见全局状态是指没有定义或引用在编码范围外的全部数据集,它们的直至不可以取得。编码范围是指所有源 文件或单个源文件。其实这两个关键字就是给编译器了一种保证,编译器信任他就不在进行一些检查操作了。

e.g


#include <stdio.h>
#include <stdlib.h>
#define M 800#define N 600#define P 700float * mempool, * memptr;
__declspec(restrict) float * ma(int size)
{ 
float * retval; 
 retval = memptr; 
 memptr += size; 
return retval;
}
__declspec(restrict) float * init(int m, int n)
{ 
float * a; 
 int i, j; 
int k=1; 
a = ma(m * n); 
 if (!a) exit(1); 
for (i=0; i<m; i++)  
 for (j=0; j<n; j++) 
 a[i*n+j] = 0.1/k++; 
return a;
}
__declspec(noalias) void multiply(float * a, float * b, float * c)
{ 
int i, j, k; 
for (j=0; j<P; j++) 
 for (i=0; i<M; i++) 
  for (k=0; k<N; k++) 
   c[i * P + j] = a[i * N + k] * b[k * P + j];
}

int main()
{ 
 float * a, * b, * c; 
mempool = (float *) malloc(sizeof(float) * (M*N + N*P + M*P)); 
if (!mempool) 
puts("ERROR: Malloc returned null"); exit(1); 
memptr = mempool; 
 a = init(M, N); 
b = init(N, P); 
c = init(M, P); 
multiply(a, b, c);
}