在 C++ 類別中使用 dllimport 和 dllexport

Microsoft 特定的

您可以使用 或 dllimport 屬性來宣告C++類別dllexport。 這些形式表示會將整個類別匯入或匯出。 以這種方式匯出的類別稱為可匯出類別。

下列範例將定義可匯出類別。 它的所有成員函式和靜態資料都會匯出:

#define DllExport   __declspec( dllexport )

class DllExport C {
   int i;
   virtual int func( void ) { return 1; }
};

請注意,禁止在可匯出類別的成員上明確使用 dllimportdllexport 屬性。

dllexport 類別

當您宣告類別 dllexport時,會匯出其所有成員函式和靜態數據成員。 您必須提供相同程式中所有這類成員的定義。 否則會產生連結器錯誤。 這項規則的例外狀況適用於純虛擬函式,您不需要為其提供明確定義。 不過,由於抽象類別的解構函式一定是由基底類別的解構函式所呼叫,因此純虛擬解構函式一定要提供定義。 請注意,這些規則同樣適用於不可匯出的類別。

如果您匯出類別類型的資料或傳回類別的函式,則務必匯出類別。

dllimport 類別

當您宣告類別 dllimport時,會匯入其所有成員函式和靜態數據成員。 與非類別類型的行為dllimportdllexport不同,靜態數據成員無法在定義類別的相同程式中dllimport指定定義。

繼承和可匯出類別

可匯出類別的所有基底類別都必須為可匯出。 否則會產生編譯器警告。 此外,同樣為類別的所有可存取成員也都必須為可匯出。 此規則允許類別 dllexport 繼承自 dllimport 類別,以及 dllimport 繼承自類別的 dllexport 類別(雖然不建議後者)。 通常,DLL 用戶端可以存取的所有項目 (根據 C++ 存取規則),都必須是可匯出介面的一部分。 這包括內嵌函式中參考的 private 資料成員。

選擇性成員匯入/匯出

因為類別中的成員函式和靜態數據隱含具有外部連結,因此您可以使用 或 dllimport 屬性來宣告它們dllexport,除非匯出整個類別。 如果匯入或匯出整個類別,則會禁止將成員函式和資料明確宣告為 dllimportdllexport 。 如果您將類別定義內的靜態數據成員宣告為 dllexport,則定義必須發生在相同程式內某處(與非類別外部連結相同)。

同樣地,您可以使用 或 dllimport 屬性來宣告成員函dllexport式。 在此情況下,您必須在相同程式內某處 dllexport 提供定義。

關於選擇性成員匯入和匯出,有幾項重點值得注意:

  • 選擇性成員匯入/匯出最適合用於提供較嚴格的匯出類別介面版本,也就是您可以為這個介面設計 DLL,公開比語言所允許更少的公用或私用功能。 另外也很適合用於微調可匯出介面:當您根據定義得知用戶端無法存取某些私用資料時,您不需要匯出整個類別。

  • 如果您匯出類別中的某一個虛擬函式,就必須匯出所有虛擬函式,或是至少要提供用戶端可以直接使用的版本。

  • 如果您在所擁有的類別中使用具有虛擬函式的選擇性成員匯入/匯出,這些函式必須位於可匯出介面中,或是定義為內嵌 (用戶端能夠看見)。

  • 如果您將成員 dllexport 定義為 ,但不包含在類別定義中,則會產生編譯程序錯誤。 您必須在類別標頭中定義成員。

  • 雖然類別成員的定義是 dllimportdllexport 允許,但您無法覆寫類別定義中指定的介面。

  • 如果您在宣告其類別定義主體以外的位置定義成員函式,則如果函式定義為 dllexportdllimport ,就會產生警告(如果這個定義與類別宣告中指定的不同)。

END Microsoft 特定的

另請參閱

dllexport、dllimport