2014-10-18 63 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