2014-10-18 114 views
0

我想弄清楚爲什麼我的DLL無法加載某些機器的原因。C + + DLL無法加載某些機器

我的應用程序:部署與安裝程序的setup.msi

C#程序。安裝程序內部是放置在應用程序的安裝目錄中的DLL。例如:

OUTDIR = c:\Program Files\MyApplicationName\%OUTDIR%\MyApplication.exe 
dir %OUTDIR%\DLL_FOLDER\\*.dll 

MYDLL.DLL

C#應用程序調用LoadLibrary通過指定:

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
private static extern IntPtr LoadLibrary(string libname); 

所以基本上

intPtr dll_handle = LoadLibrary("myDll.dll"); 

被調用,我們使用dll_handle來調用所需的功能。

到目前爲止,這已經在我部署它的機器的5/7上工作......我在這裏製造的明顯錯誤是什麼? :-)

感謝您的幫助!

+3

通常這是一個DLL依賴問題。檢查依賴關係walker DLL是否擁有它依賴的所有東西。 – Timbo 2014-10-18 14:55:25

+0

Dll的搜索路徑中是否有'DLL_FOLDER'?如果不是的話,爲什麼不能直接將DLL放入'%OUTDIR%'本身? – PeterT 2014-10-18 14:56:20

+0

@彼得特爾:是的彼得我可以把它放在同一個文件夾中。 DLL_FOLDER被用來「保持整潔」。 – 2014-10-18 15:38:09

回答

6

最有可能的解釋是:

  1. DLL不能被發現。由於您沒有指定完整路徑,因此您需要依靠Dynamic-Link Library Search Order來找到它。將DLL放在與可執行文件相同的目錄中是確保找到它並找到正確版本的常用方法。
  2. 該DLL具有不匹配的位。例如,你有一個64位進程和一個32位DLL,反之亦然。
  3. 該DLL被發現,並具有正確的位,但該DLL的依賴關係無法解析。通常這意味着需要在目標機器上安裝合適的MSVC運行時。

第一診斷步驟,採取的是檢查的LoadLibrary返回值,如果它是NULL然後調用GetLastError檢索錯誤代碼。在p/invoke中,您可以這樣做:

IntPtr lib = LoadLibrary(...); 
if (lib == IntPtr.Zero) 
    throw new Win32Exception(); 

您可以使用像Dependency Walker這樣的工具來進一步調試問題。

+0

Hefferman,感謝您的詳細回答!我對第1和第2點非常有信心,但是我懷疑它可能與您建議的MSVC運行時相關。使用依賴walker我發現有時失敗的DLL在MSVCP100.DLL,MSVCR100.DLL,VCOMP100.DLL和kenerl32.dll上是depedant。我懷疑前3個與VS運行時相關? – 2014-10-18 15:46:14

+0

噢,如果我在失敗的機器上運行依賴關係的步行者,它能告訴我哪個依賴關係在特定的機器上缺失了嗎? – 2014-10-18 15:46:50

+0

確實根據dependencywalker,目標機器上缺少VCOMP100.dll,最佳的操作過程是什麼?在每臺部署機器上安裝VS2010運行時? – 2014-10-18 15:58:37