文章目錄
- 1. DLL文件路徑問題
- 2. 依賴的運行時庫缺失
- 3. 平臺不匹配(x86/x64)
- 4. 導出函數名稱不匹配
- 5. DLL文件損壞或權限問題
- 6. 運行時庫沖突(MT/MD不匹配)
- 7. 使用DLLImport時的常見錯誤
- 總結步驟
在C#中調用C++動態庫時出現System.DllNotFoundException
錯誤,即使添加了extern "C"
,仍可能有以下原因及解決方案:
1. DLL文件路徑問題
C#默認在以下位置查找DLL(按優先級排序):
- 應用程序的
bin\Debug
或bin\Release
目錄(輸出目錄)。 System32
或SysWOW64
目錄(取決于平臺)。- PATH環境變量中的路徑。
解決方法:
- 將
TestDll.dll
直接復制到C#項目的輸出目錄(如bin\Debug
)。 - 在C#項目中設置DLL的“復制到輸出目錄”屬性:
- 右鍵DLL文件 → 屬性 → 復制到輸出目錄:始終復制。
- 或在代碼中指定絕對路徑(不推薦):
[DllImport(@"C:\Full\Path\To\TestDll.dll")]
2. 依賴的運行時庫缺失
C++ DLL可能依賴其他庫(如MSVCRxxx.dll
、VCRUNTIMExxx.dll
或第三方DLL)。若這些依賴未正確部署,會導致加載失敗。
解決方法:
- 使用工具檢查依賴項:
- 使用 Dependency Walker(舊版)或 Visual Studio的“依賴項查看器”(如
dumpbin /dependents TestDll.dll
)檢查缺失的依賴。 - 用Everything直接搜索拖動到當前exe目錄,全部拷貝過來肯定能運行。
- 刪除某個DLL再看能否運行。
- 使用同樣的步驟檢查次級依賴的dll。
- 使用 Dependency Walker(舊版)或 Visual Studio的“依賴項查看器”(如
- 安裝VC++運行時:
- 如果依賴VC++運行時庫(如
MSVCP140.dll
),安裝對應版本的Visual C++ Redistributable。
- 如果依賴VC++運行時庫(如
- 將依賴DLL與主DLL放在同一目錄。
3. 平臺不匹配(x86/x64)
如果C#項目與C++ DLL的編譯平臺(x86/x64)不一致,會導致無法加載。
解決方法:
- 確保C#項目的目標平臺與DLL的平臺一致:
- 右鍵C#項目 → 屬性 → 生成 → 目標平臺(選擇x86或x64)。
- 如果DLL是64位的,C#項目必須設為
x64
;如果是32位的,設為x86
(不能使用Any CPU
)。
4. 導出函數名稱不匹配
即使使用extern "C"
,仍需確保導出函數名稱完全正確(包括大小寫、修飾名)。
驗證方法:
- 使用
dumpbin
工具查看導出的函數名:dumpbin /exports TestDll.dll
- 檢查C#中
[DllImport]
的EntryPoint
名稱是否與導出名稱一致。
示例:
C++代碼:
extern "C" __declspec(dllexport) int Add(int a, int b);
導出的函數名通常是Add
(無修飾),C#應聲明為:
[DllImport("TestDll.dll")]
public static extern int Add(int a, int b);
5. DLL文件損壞或權限問題
- 確保DLL文件未被占用或損壞(嘗試重新編譯C++項目)。
- 檢查文件權限:確保應用程序有權限讀取DLL。
6. 運行時庫沖突(MT/MD不匹配)
如果C++ DLL的運行時庫設置(/MT
或/MD
)與C#環境不兼容,可能導致沖突。
解決方法:
- 在C++項目中統一使用
/MD
(動態鏈接運行時庫):- 項目屬性 → C/C++ → 代碼生成 → 運行時庫 → 選擇
多線程DLL (/MD)
。
- 項目屬性 → C/C++ → 代碼生成 → 運行時庫 → 選擇
7. 使用DLLImport時的常見錯誤
- 確保函數調用約定一致(默認為
__stdcall
,但C++通常用__cdecl
)。[DllImport("TestDll.dll", CallingConvention = CallingConvention.Cdecl)]
總結步驟
- 確認DLL位置:將DLL放在C#輸出目錄。
- 檢查依賴項:確保所有依賴的DLL存在。缺少目標XXXdll的依賴,例如要用到的是A.dll,A.dll用到時需要添加B.dll動態庫文件,在用到時需要兩個dll同時存在。其中,B.dll導出有問題時通過dumpbin檢查A.dll不能檢查出來,需要進一步檢查B.dll。
- 匹配平臺:統一x86或x64。
- 驗證導出函數:使用
dumpbin
檢查名稱。 - 安裝VC++運行時:確保目標機器已安裝。
通過逐步排查上述問題,通常可以解決DllNotFoundException
。