首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ __declspec(dllimport) 與 dllexport:DLL 導入導出機制與定位定義

     編輯:程式設計綜合問答

頭文件 local.h:

__declspec(dllimport) WORD WINAPI PrintScreen(HWND, WORD, WORD, WORD, LPSTR, BOOL);

.c 文件中呼叫此函式,編譯器提示與 winuser.h 中 3 參數同名函式衝突(實則為誤讀,詳見下文)。

核心機制

  • __declspec(dllexport):在 **DLL 建置專案** 中標記函式/類別**導出**,生成匯出表供外部連結。
  • __declspec(dllimport):在 **使用 DLL 的專案** 中標記**導入**,指示編譯器產生間接呼叫 (thunk),透過 IAT (Import Address Table) 解析位址。

標準用法:巨集切換

// MyDLL.h
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif

MYDLL_API WORD WINAPI PrintScreen(HWND, WORD, WORD, WORD, LPSTR, BOOL);
  • DLL 專案定義 MYDLL_EXPORTS (VS 專案屬性 → C/C++ → Preprocessor),見 dllexport。
  • 調用專案**不定義**,見 dllimport。

如何找到定義來源

  1. **檢查 .lib 匯入庫**:dumpbin /exports YourDll.lib 列出匯出符號,確認 PrintScreen 存在。
  2. **檢查 DLL 相依性**:dumpbin /dependents YourApp.exe 確認連結了哪個 DLL。
  3. **原始碼搜尋**:在方案中搜尋 PrintScreen 定義 (非宣告),通常在 DLL 專案的 .cpp 文件中。
  4. **避免命名衝突**:**絕不可與系統 API 同名**。若必須同名,將自訂函式置於**獨立命名空間**,並在調用處加前綴 MyNamespace::PrintScreen。

關於 winuser.h 衝突說明

winuser.h 中確有 PrintScreen 但參數不同(舊版/特定 SDK)。**編譯器報「重定義」實為參數不匹配的多載衝突**。解決:重命名自訂函式 (如 MyPrintScreen) 或置入命名空間,絕不與系統全域命名空間同名。

掌握 dllexport/dllimport 雙模式巨集與命名空間隔離,是 C++ DLL 開發的基本功。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved