一般規則和限制
Microsoft 特定的
如果您宣告沒有 或
dllexport
屬性的dllimport
函式或物件,則函式或物件不會被視為 DLL 介面的一部分。 因此,函式或物件的定義必須存在該模組中,或是相同程式的另一個模組中。 若要使 DLL 介面的函式或物件部分成為 ,您必須將另一個模組中的函式或物件定義宣告為dllexport
。 否則會產生連結器錯誤。如果您使用 屬性宣告函式或物件
dllexport
,其定義必須出現在相同程式的某個模組中。 否則會產生連結器錯誤。如果程式中的單一模組同時包含
dllimport
相同函式或物件的 和dllexport
宣告,則dllexport
屬性會優先于dllimport
屬性。 不過,這樣會產生編譯器警告。 例如:__declspec( dllimport ) int i; __declspec( dllexport ) int i; // Warning; inconsistent; // dllexport takes precedence.
在 C++ 中,您可以初始化全域宣告或靜態本機資料指標,或是使用 屬性宣告
dllimport
的資料物件位址,以在 C 中產生錯誤。此外,您可以使用以dllimport
屬性宣告的函式位址,初始化靜態區域函式指標。 在 C 中,此類指派會將指標設定為 DLL 匯入 Thunk (將控制權傳送至函式的程式碼 Stub) 的位址,而不是設定為函式的位址。 在 C++ 中,它會將指標設定為函式的位址。 例如:__declspec( dllimport ) void func1( void ); __declspec( dllimport ) int i; int *pi = &i; // Error in C static void ( *pf )( void ) = &func1; // Address of thunk in C, // function in C++ void func2() { static int *pi = &i; // Error in C static void ( *pf )( void ) = &func1; // Address of thunk in C, // function in C++ }
不過,由於在物件宣告中包含 屬性的程式
dllexport
必須提供程式中該物件的定義,因此您可以使用函式的dllexport
位址初始化全域或本機靜態函式指標。 同樣地,您可以使用dllexport
資料物件的位址初始化全域或區域靜態資料指標。 例如,下列程式碼不會在 C 或 C++ 中產生錯誤:__declspec( dllexport ) void func1( void ); __declspec( dllexport ) int i; int *pi = &i; // Okay static void ( *pf )( void ) = &func1; // Okay void func2() { static int *pi = &i; // Okay static void ( *pf )( void ) = &func1; // Okay }
如果您套用
dllexport
至具有未標示dllexport
為 之基類的一般類別,編譯器將會產生 C4275。如果基底類別是類別樣板的特製化,則編譯器會產生相同的警告。 若要解決此問題,請使用
dllexport
標記基類。 類別範本特製化的問題在於放置__declspec(dllexport)
的位置;您不允許標記類別範本。 相反地,明確地具現化類別範本,並以 標記這個明確的具現化dllexport
。 例如:template class __declspec(dllexport) B<int>; class __declspec(dllexport) D : public B<int> { // ...
如果樣板引數為衍生類別,則這個解決方法會失敗。 例如:
class __declspec(dllexport) D : public B<D> { // ...
由於這是範本的常見模式,所以編譯器在套用至具有一或多個基類的類別時,以及當一或多個基類是類別範本的特製化時,會變更
dllexport
的語意。 在此情況下,編譯器會隱含地套用dllexport
至類別範本的特製化。 您可以執行下列動作,而不會收到警告:class __declspec(dllexport) D : public B<D> { // ...
END Microsoft 特定的
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應