c++中__declspec用法總結
“__declspec”是Microsoft c++中專用的關鍵字,它配合著一些屬性可以對標準C++進行擴充。這些屬性有:align、allocate、deprecated、 dllexport、dllimport、 naked、noinline、noreturn、nothrow、novtable、selectany、thread、property和uuid。
1,_declspec
(1)用法一定義介面
usingnamespace std;
#define interface class __declspec(novtable)
interface
{
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 同等於如下:
2{
3public:
4 virtualbool Decode(char* lpDataSrc,unsigned
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
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匯出。我要給別人用。
如,
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()呼叫。