__declspec用法總結(Microsoft c++)


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

1,_declspec
(1)用法一定義接口

#include <IOSTREAM>
using namespace std;

#define interface class __declspec(novtable)

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

ICodec 同等於如下:

1class ICodec
2{
3public:
4    virtual bool Decode(char * lpDataSrc,unsigned int nSrcLen,char * lpDataDst,unsigned int *pnDstLen)=0;
5    virtual bool 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>
 5using namespace 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    };3031    void PutY(int n,int y)32    {33        m_yvalues[n] = y;34    };3536    string GetZ(string key)37    {38        return m_zvalues[key];39    };4041    void PutZ(string key,string z)42    {43        m_zvalues[key] = z;44    };4546};4748int 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;5758    getch();59    return 0;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()調用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM