msvcr71.dll Windows Server 2008 上 IIS 7 应用程序池崩溃,ASP.NET 4



我正在处理一个项目,该项目需要一个用托管代码包装的 C 库。C 库是为 32 位编译的,我已经发现它需要 msvcr71.dll .问题是,无论出于何种原因,此DLL都不随Windows Server 2008一起出现在SysWOW64目录中。

我已经从系统上的 SQL 管理工作室复制了 DLL,我可以验证它是否在服务器上的独立 EXE 中工作。没有什么可以阻止它工作。

然而。。。当我将其链接到我的 ASP.NET 应用程序并确保我的库的 DLL 和 msvcr71.dll 都在我的/bin目录中时,我的站点的应用程序池从我下面掉出来。 werfault.exe启动,吃掉一堆CPU和RAM,然后消失,在事件查看器中留下这个几乎无用的日志。

然后,应用程序池将重新启动并等待再次失败。它在集成模式下与 .NET 4 一起运行。该网站基于 MVC 3。

Faulting application name: w3wp.exe, version: 7.5.7601.17514, time stamp: 0x4ce7a5f8
Faulting module name: ntdll.dll, version: 6.1.7601.17725, time stamp: 0x4ec49b8f
Exception code: 0xc0000374
Fault offset: 0x000ce6c3
Faulting process id: 0x998
Faulting application start time: 0x01cd753eb1fcd760
Faulting application path: C:WindowsSysWOW64inetsrvw3wp.exe
Faulting module path: C:WindowsSysWOW64ntdll.dll
Report Id: 7b54f020-e132-11e1-a34d-404094d3cf82

这到底是怎么回事?我很想将 DLL 直接链接到我的 ASP.NET 站点,但我正处于编写代理应用程序的边缘......如果可能的话,我想避免这种黑客攻击。谢谢。

旁注 所有这些都在我的本地计算机上运行良好。只有在服务器上,我才在将其链接到 IIS 时遇到真正的麻烦。

更新

在 IIS 内部运行时,这似乎是一个互操作问题,尤其是对于字符串方法...我现在正在调查它...

http://blogs.msdn.com/b/asiatech/archive/2009/12/24/net-application-may-crash-on-windows-2008-when-calling-function-from-native-c-dll.aspx

讨厌回答我自己的问题,但它需要为其他人记录一个解决方案。我在这里遇到的核心问题实际上并没有msvcr71.dll(最终我确实根据 C 运行时msvcr100.dll 10 版重新编译了相关库的原始 C 源代码,因为它默认包含在 Windows Server 2008 中。

我仍在针对 x86 运行库。然而,这里真正的问题是,存在某种内存管理错误(或功能,由您决定),导致 IIS 7 在 .NET 中使用字符串对 P/调用执行互操作时崩溃。我认为它旨在作为安全功能...谁知道呢。

查看上面问题更新中列出的文章,了解这方面的部分详细信息:

http://blogs.msdn.com/b/asiatech/archive/2009/12/24/net-application-may-crash-on-windows-2008-when-calling-function-from-native-c-dll.aspx

我正在使用的特定库适用于来自 GIS 工具的 Shapefile,如果您很好奇的话。

http://shapelib.maptools.org/

这对我来说有些道理,但我的库是用 C 而不是C++编写的。无论如何,这两种语言都不是我的强项,我找不到 C 编译器中存在的CoTaskMemFree方法。这可能是我自己的错,但我真的没有时间学习和重写一些古老的 C 代码。

发现我不能使用 .NET 方法封送字符串,而是从 IntPtr 手动执行此操作以防止 IIS 崩溃。

这是我的原始导入:

    [DllImport("shapelib.dll", CharSet = CharSet.Ansi)]
public static extern string DBFReadStringAttribute (IntPtr hDBF, int iShape, int iField);

。这是我必须将其更改为的内容:

    [DllImport("shapelib.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr DBFReadStringAttribute (IntPtr hDBF, int iShape, int iField);

该更改本身阻止了应用程序崩溃。然后我不得不创建这种技巧来拉出琴弦。我知道这肯定远非乐观,但这是我目前能做的最好的事情。

这是我最终所做的...

public static string DBFReadStringAttribute(IntPtr hDBF, int iShape, int iField)
{
    IntPtr dataPtr = _DBFReadStringAttribute(hDBF, iShape, iField);
    string output = Marshal.PtrToStringAnsi(dataPtr, 255); //255 is the supposed max length for DBF databases
    int idx = output.IndexOf('');
    string strData;
    if (idx > 0)
        strData = output.Substring(0, idx).Trim();
    else
        strData = "";
    return strData;
}
[DllImport("shapelib.dll", CharSet = CharSet.Ansi, EntryPoint = "DBFReadStringAttribute")]
private static extern IntPtr _DBFReadStringAttribute (IntPtr hDBF, int iShape, int iField);

附加说明

无论出于何种原因Marshal.PtrToStringAnsi(dataPtr)都没有正确检索字符串(它会损坏)。我必须设置一个最大长度并自己解析它。

最新更新