在Windows平台下:
您可以使用dllimport或dllexport屬性聲明C ++類。這些形式意味着導入或導出整個類。以這種方式導出的類稱為可導出類。
以下示例定義可導出的類。導出其所有成員函數和靜態數據:
#define DllExport __declspec( dllexport ) class DllExport C { int i; virtual int func( void ) { return 1; } };
請注意,禁止在可導出類的成員上顯式使用 dllimport 和 dllexport 屬性。
dllexport類
聲明類dllexport時,將導出其所有成員函數和靜態數據成員。您必須在同一程序中提供所有此類成員的定義。否則,將生成鏈接器錯誤。此規則的一個例外適用於純虛函數,您無需為其提供顯式定義。但是,因為抽象類的析構函數總是由基類的析構函數調用,所以純虛擬析構函數必須始終提供定義。請注意,這些規則對於不可導出的類是相同的。
如果導出類類型的數據或返回類的函數,請確保導出該類。
dllimport類
聲明類dllimport時,將導入其所有成員函數和靜態數據成員。與dllimport和dllexport在非類類型上的行為不同,靜態數據成員不能在定義dllimport類的同一程序中指定定義。
繼承和可導出的類
可導出類的所有基類都必須是可導出的。如果不是,則生成編譯器警告。此外,所有可訪問的成員也必須是可導出的。該規則允許DLLEXPORT類從繼承dllimport的類和dllimport的類從繼承DLLEXPORT類(但不建議后者)。通常,DLL調用者可訪問的所有內容(根據C ++訪問規則)應該是可導出接口的一部分。這包括內聯函數中引用的私有數據成員。
選擇成員導入/導出
由於類中的成員函數和靜態數據隱式具有外部鏈接,因此可以使用dllimport或dllexport屬性聲明它們,除非導出整個類。如果導入或導出整個類,則禁止將成員函數和數據顯式聲明為dllimport或dllexport。如果將類定義中的靜態數據成員聲明為dllexport,則定義必須出現在同一程序中的某個位置(與非類外部鏈接一樣)。
同樣,您可以使用dllimport或dllexport屬性聲明成員函數。在這種情況下,您必須在同一程序中的某處提供dllexport定義。
值得注意的是有關選擇性成員導入和導出的幾個要點:
-
選擇性成員導入/導出最適用於提供限制性更強的導出類接口的版本; 也就是說,您可以設計一個DLL,該DLL暴露的公共和私有功能比該語言允許的更少。它對於微調可導出接口也很有用:當您知道調用者(根據定義)無法訪問某些私有數據時,您無需導出整個類。
-
如果在類中導出一個虛函數,則必須導出所有虛函數,或者至少提供調用者可以直接使用的版本。
-
如果您有一個使用虛擬函數選擇性成員導入/導出的類,則這些函數必須位於可導出接口中或內聯定義(對客戶端可見)。
-
如果將成員定義為dllexport但未將其包含在類定義中,則會生成編譯器錯誤。您必須在類標頭中定義該成員。
-
雖然允許將類成員定義為dllimport或dllexport,但是不能覆蓋類定義中指定的接口。
-
如果在聲明它的類定義主體之外的位置定義成員函數,則在函數定義為dllexport或dllimport時生成警告(如果此定義與類聲明中指定的定義不同)。