1. 程式人生 > >C#呼叫CLR C++ DLL異常分析

C#呼叫CLR C++ DLL異常分析

前言

在使用C#呼叫CLR C++ DLL開發程式完成後在本機上執行正常(本機為Win8.1 64位系統),在將生成的程式複製到客戶機電腦上時(Win7 32位作業系統),遇到了如下所示提示:

未能載入檔案或程式集“XXXX.dll”或它的某一個依賴項,不是有效的WIN32位應用程式。(異常來自 HRESULT:0x800700C1)

分析

分析XXXX.dll的依賴關係

使用Depends.Exe(Visual Studio工具,該類工具很多可根據使用習慣來選擇)分析XXXX.dll中存在的依賴關係,分析後發現存在存在一個MFC和msvcr的DLL是客戶上沒有的,直接根據名稱在硬碟中查詢即可知道是否存在,將本機(Win8.1開發機)上C:\Windows\System32下對應dll複製到客戶機程式執行目錄下,程式依舊崩潰。

網上查詢該問題解決方案

基本上都是說X64程式呼叫了X86的DLL,存在相互呼叫的問題。但是我開發環境顯然配置等都是正確的,不然按道理本機程式就應該無法正常執行,考慮可能是存在編譯環境等因素導致異常。

下載eXeScope(PE格式檔案檢視工具,具體可根據個人喜好進行選擇),先後分析exe和dll的中對系統版本的支援資訊(作業系統版本支援資訊)和執行平臺資訊(X64還是X86):

  • 程式執行平臺資訊主要檢視Coff Header欄位中0x0000011C位置值,該程式和呼叫DLL中該位置值都為0x014C(I386即32位系統執行程式。)

  • 程式和DLL執行作業系統平臺主要檢視Optional Header中OS Major Version和OS Minor Version資訊,在命令列下直接輸入ver即可檢視到本機作業系統版本的編號資訊。如在我Win8.1作業系統上執行ver,可以看到如下提示資訊:Microsoft Windows [版本 6.3.9600]

以上操作證明程式和生成DLL都是32位環境執行並無問題。

懷疑還是DLL依賴上還是存在問題

進入正題,此處才是重點。既然本機能執行那麼本機肯定有對應DLL載入資訊,除錯程式時看到Output下輸出如下資訊:

'WindowsFormsApplication1.exe': Loaded 'C:\Windows\SysWOW64\mfc110ud.dll', Symbols loaded.
'WindowsFormsApplication1.exe': Loaded 'C:\Windows\SysWOW64\msvcr110d.dll', Symbols loaded.

突然發現自己複製到客戶機上的dll位置與Output輸出位置資訊不一致,然後將SysWOW64中對應DLL替換前面複製過去的dll資訊,程式正常執行。原因很簡單就是前面複製的DLL是64位系統使用的,32位系統無法識別所以出現瞭如上所示提示資訊。

如果意外碰到類似存在DLL依賴關係都可以通過程式啟動時的Output輸出資訊來將對應DLL複製到新的環境一般應該都可解決問題,如果是應用程式則可以通過依賴關係檢視程式複製對應的DLL到新程式目錄即可。

擴充套件閱讀