使用 .DEF 檔匯入

如果您選擇使用 __declspec(dllimport) 和 .def 檔,則您應該變更 .def 檔,使用 DATA 來取代 CONSTANT,以降低不正確的程式設計造成問題的可能性:

// project.def
LIBRARY project
EXPORTS
   ulDataInDll   DATA

下表顯示問題產生的原因。

Keyword

在匯入程式庫裡發出

匯出

CONSTANT

_imp_ulDataInDll_ulDataInDll

_ulDataInDll

DATA

_imp_ulDataInDll

_ulDataInDll

使用 __declspec(dllimport) 和 CONSTANT 會列出 .lib DLL 匯入程式庫的 imp 版本和未裝飾名稱 (Undecorated Name),此程式庫是為允許明確連結而建立。使用 __declspec(dllimport) 和 DATA 則會列出名稱的 imp 版本。

如果您使用 CONSTANT,則可以使用下列任一種程式碼建構來存取 ulDataInDll:

__declspec(dllimport) ULONG ulDataInDll; /*prototype*/
if (ulDataInDll == 0L)   /*sample code fragment*/

-或-

ULONG *ulDataInDll;      /*prototype*/
if (*ulDataInDll == 0L)  /*sample code fragment*/

然而,如果您在 .def 檔中使用 DATA,則只有使用下列定義編譯的程式碼可以存取 ulDataInDll 變數:

__declspec(dllimport) ULONG ulDataInDll;

if (ulDataInDll == 0L)   /*sample code fragment*/

CONSTANT 是較危險的使用方式,因為如果您忘記已使用其他的間接傳遞層級,您很可能會存取到變數的匯入位址表指標 — 而不是變數本身。這類型的問題通常會明示為存取違規,因為編譯器和連結器目前是將匯入位址表設為唯讀。

如果在 .def 檔中看到 CONSTANT,則目前的 Visual C++ 連結器會發出警告說明這個情況。使用 CONSTANT 的唯一真正理由,是您無法重新編譯某些物件檔 (因為標頭檔在原型上未列出 __declspec(dllimport))。

請參閱

概念

匯入至應用程式