从C#网站调用32位Delphi DLL文件时遇到问题。代码通常运行正常,但偶尔会出错,
*无法加载DLL'':找不到指定的模块。 (HRESULT异常:0x8007007E)。
在我回收网站的应用程序池之前,此问题仍然存在,然后再次正常运行。
在同一台服务器上,还有一个调用同一组DLL文件的Web服务。此Web服务似乎与网站没有相同的问题。
两个应用程序都使用.NET Framework 3.5,IIS上的单独应用程序池。
这是我用来包装DLL文件的代码:
public sealed class Mapper
{
static Mapper instance = null;
[DllImport("kernel32.dll")]
private static extern bool SetDllDirectory(string lpPathName);
private Mapper()
{
SetDllDirectory(ConfigManager.Path);
}
public static Mapper Instance
{
get
{
if (instance == null)
{
instance = new Mapper();
}
return instance;
}
}
public int Foo(string bar, ref double val)
{
return Loader.Foo(bar, ref val);
}
}
public static class Loader
{
[DllImport("some.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, EntryPoint = "foo")]
public static extern int Foo(string bar, ref double val);
}
然后我称之为:
double val = 0.0;
Mapper.Instance.Foo("bar", ref val);
为什么它会“随机”无法加载DLL'':找不到指定的模块。 (来自HRESULT的异常:0x8007007E)。?
另一个问题是我无法在开发环境中复制该问题。我认为由于两个应用程序调用相同的DLL文件,可能会发生一些锁定。为了复制这个,我创建了一个生成多个线程并重复调用32位DLL文件的应用程序,然后使用该网站调用这些相同的DLL文件。我仍然无法复制这个问题。
我能想到的一些可能的修复:
我该怎么办?
答案 0 :(得分:1)
我不知道究竟是什么导致了这个问题,但根据我的经验,此错误消息可能是由以下原因引起的:
您正在使用的DLL文件需要一个运行时库,该库在加载时不可用(如Visual C ++运行时库)。您需要库的确切版本。例如,如果您的DLL文件是使用运行时Visual Studio 2008 SP1编写的,则需要完全相同的版本。
DLL文件的一个依赖项不可用。您可以使用Dependency Walker。
此外,您必须确保您的DLL文件和调用应用程序都是32位或64位。当我想从64位应用程序调用32位DLL文件时,有时会出现相同的错误。
我知道这不是真正的答案,但我希望它能帮助您找到解决方案。
答案 1 :(得分:0)
为了解决这个问题(它现在已经停止发生),我按原样保留了映射器代码,但是在调用应用程序中我手动设置路径(即使映射器DLL文件大部分时间也是这样做的。)
因此,在主应用程序中,我调用了附加DLL文件所在目录的路径。
private static void AddEnvironmentPaths(string[] paths)
{
string path = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
path += ";" + string.Join(";", paths);
Environment.SetEnvironmentVariable("PATH", path);
}
奇怪的是,mapper类大部分时间都在工作,但有时会停止。使用上面的代码添加路径似乎解决了这个问题。