1. 程式人生 > >c++中__declspec用法總結

c++中__declspec用法總結

“__declspec”是Microsoft c++中專用的關鍵字,它配合著一些屬性可以對標準C++進行擴充。這些屬性有:align、allocate、deprecated、 dllexport、dllimport、 naked、noinline、noreturn、nothrow、novtable、selectany、thread、property和uuid。

1,_declspec
(1)用法一定義介面

#include <IOSTREAM>
usingnamespace std;

#define interface class __declspec(novtable)

interface
 ICodec
{
public:
    
virtualbool Decode(char* lpDataSrc,unsigned int nSrcLen,char* lpDataDst,unsigned int*pnDstLen);
    
virtualbool Encode(char* lpDataSrc,unsigned int nSrcLen,char* lpDataDst,unsigned int*pnDstLen);
}
;

ICodec 同等於如下:

1class ICodec
2{
3public:
4    virtualbool Decode(char* lpDataSrc,unsigned 
int nSrcLen,char* lpDataDst,unsigned int*pnDstLen)=0;
5    virtualbool Encode(char* lpDataSrc,unsigned int nSrcLen,char* lpDataDst,unsigned int*pnDstLen)=0;
6}
;

2,用法二,定義類的屬性
屬性,是面向物件程式設計中不可缺少的元素,廣義的屬性是用來描述一個物件所處於的狀態。而我們這篇文章所說的屬性是狹義的,指能用“=”操作符對類的一個數據進行get或set操作,而且能控制get和set的權
 1#include <IOSTREAM> 2#include 
<map> 3#include <string> 4#include <CONIO.H> 5usingnamespace std;
 6
 7class propertytest
 8{
 9    int m_xvalue;
10    int m_yvalues[100];
11    map<string,string> m_zvalues;
12public:
13    __declspec(property(get=GetX, put=PutX)) int x;
14    __declspec(property(get=GetY, put=PutY)) int y[];
15    __declspec(property(get=GetZ, put=PutZ)) int z[];
16
17    int GetX()
18    {
19        return m_xvalue;
20    }
;
21    void PutX(int x)
22    {
23        m_xvalue = x;
24    }
;
25    
26    int GetY(int n)
27    {
28        return m_yvalues[n];
29    }
;
30
31    void PutY(int n,int y)
32    {
33        m_yvalues[n] = y;
34    }
;
35
36    string GetZ(string key)
37    {
38        return m_zvalues[key];
39    }
;
40
41    void PutZ(string key,string z)
42    {
43        m_zvalues[key] = z;
44    }
;
45
46}
;
47
48int main(int argc, char* argv[])
49{
50    propertytest test;
51    test.x =3;
52    test.y[3=4;
53    test.z["aaa"="aaa";
54    std::cout << test.x <<std::endl;
55    std::cout << test.y[3<<std::endl;
56    std::cout << test.z["aaa"<<std::endl;
57
58    getch();
59    return0;
60}

3,用法三,
_declspec(dllimport)     是說這個函式是從別的DLL匯入。我要用。
_declspec(dllexport)   是說這個函式要從本DLL匯出。我要給別人用。

如,

#define Test_API __declspec(dllexport)

Class test
{
   
public:
   Test_API HRESULT WINAPI Initialize(LPCTSTR filename);
}

4. __declspec(align(16)) struct SS{ int a,b; };
 它與#pragma pack()是一對兄弟,前者規定了對齊的最小值,後者規定了對齊的最大值。同時出現時,前者優先順序高。 __declspec(align())的一個特點是,它僅僅規定了資料對齊的位置,而沒有規定資料實際佔用的記憶體長度,當指定的資料被放置在確定的位置之後,其後的資料填充仍然是按照#pragma pack規定的方式填充的,這時候類/結構的實際大小和記憶體格局的規則是這樣的:在__declspec(align())之前,資料按照#pragma pack規定的方式填充,如前所述。當遇到__declspec(align())的時候,首先尋找距離當前偏移向後最近的對齊點(滿足對齊長度為max (資料自身長度,指定值)),然後把被指定的資料型別從這個點開始填充,其後的資料型別從它的後面開始,仍然按照#pragma pack填充,直到遇到下一個__declspec(align())。當所有資料填充完畢,把結構的整體對齊數值和__declspec(align ())規定的值做比較,取其中較大的作為整個結構的對齊長度。 特別的,當__declspec(align())指定的數值比對應型別長度小的時候,這個指定不起作用。

5. #pragma section("segname",read)
    / __declspec(allocate("segname")) int i = 0;
    / int main(){ return 1;};
 此關鍵詞必須跟隨code_seg,const_seg,data_seg,init_seg,section關鍵字之後使用,以上例子使用了section關鍵字。使用此關鍵字將告知編譯器,其後的變數間被分配在那個資料段。

6. __declspec(deprecated(MY_TEXT)) void func(int) {}
 與pragma deprecated()相同。此聲明後,如果在同一作用域中使用func(int)函式,將被提醒c4996警告。

7. __declspec(jitintrinsic)
 用於標記一個函式或元素為64位公共語言執行時。具體用法未見到。

8. __declspec( naked ) int func( formal_parameters ) {}
 此關鍵字僅用於x86系統,多用於硬體驅動。此關鍵字可以使編譯器在生成程式碼時不包含任何註釋或標記。僅可以對函式的定義使用,不能用於資料宣告、定義,或者函式的宣告。

9. __declspec(restrict) float * init(int m, int n) {};
   & __declspec(noalias) void multiply(float * a, float * b, float * c) {};// 優化必用!
 __declspec (restrict)僅適用於返回指標的函式宣告,如 __declspec(restrict) void *malloc(size_t size);restrict declspec 適用於返回非別名指標的函式。此關鍵字用於 malloc 的 C 執行時庫實現,因為它決不會返回已經在當前程式中使用的指標值(除非您執行某個非法操作,如在記憶體已被釋放之後使用它)。restrict declspec 為編譯器提供執行編譯器優化的更多資訊。對於編譯器來說,最大的困難之一是確定哪些指標會與其他指標混淆,而使用這些資訊對編譯器很有幫助。有必要指出,這是對編譯器的一個承諾,編譯器並不對其進行驗證。如果您的程式不恰當地使用 restrict declspec,則該程式的行為會不正確。 __declspec(noalias)也是僅適用於函式,它指出該函式是半純粹的函式。半純粹的函式是指僅引用或修改區域性變數、引數和第一層間接引數。此 declspec 是對編譯器的一個承諾,如果該函式引用全域性變數或第二層間接指標引數,則編譯器會生成將中斷應用程式的程式碼。

10. class X {
   / __declspec(noinline) int mbrfunc() { return 0; /* will not inline*/ };
 在類中宣告一個函式不需要內聯。

11. __declspec(noreturn) extern void fatal () {}
 不需要返回值。

12. void __declspec(nothrow) __stdcall f2();
 不存在異常丟擲。

13. struct __declspec(novtable) X { virtual void mf(); };
    / struct Y : public X {void mf() {printf_s("In Y/n");}};
 此關鍵字標記的類或結構不能直接例項化,否則將引發AV錯誤(access violation)。此關鍵字的宣告將阻止編譯器對構造和解構函式的vfptr的初始化。可優化編譯後代碼大小。

12. struct S {   int i;
    / void putprop(int j) {  i = j; }
    / int getprop() { return i; }
    / __declspec(property(get = getprop, put = putprop)) int the_prop;};
  此關鍵字與C#中get & set屬性相同,可定義實現針對一個欄位的可讀或可寫。以上例子,可以使用(如果例項化S為ss)如:ss.the_prop = 156;(此時,ss.i == 156)接著如果:cout<< s.the_prop;(此時將呼叫getprop,使返回156)。

14. __declspec(selectany)(轉)
 在MFC,ATL的原始碼中充斥著__declspec (selectany)的宣告。selectany可以讓我們在.h檔案中初始化一個全域性變數而不是隻能放在.cpp中。比如有一個類,其中有一個靜態變數,那麼我們可以在.h中通過類似__declspec(selectany) type class::variable = value; 這樣的程式碼來初始化這個全域性變數。既是該.h被多次include,連結器也會為我們剔除多重定義的錯誤。對於template的程式設計會有很多便利。

15. __declspec(thread) int in_One_Thread;
 宣告in_One_Thread為執行緒區域性變數並具有執行緒儲存時限,以便連結器安排在建立執行緒時自動分配的儲存。

16. struct __declspec(uuid("00000000-0000-0000-c000-000000000046")) IUnknown;
 將具有唯一表示符號的已註冊內容宣告為一個變數,可使用__uuidof()呼叫。