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

Microsoft 特定的

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

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

#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 資料成員。

選擇性成員匯入/匯出

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

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

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

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

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

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

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

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

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

END Microsoft 特定的

另請參閱

dllexport、dllimport