stackoverflow with dllimport from IIS

本文关键字:IIS from dllimport with stackoverflow | 更新日期: 2023-09-27 18:20:07

场景

我为一个C dll制作了一个Wrapper类,这样我就可以从托管代码中调用它的函数,并可以从C#WCF服务中访问它们。一切似乎都很好,但当在C库中分配大量内存时。IIS似乎不喜欢它。它会给我一个stackoverflow异常。

问题

在C dll中分配内存时。它在IIS中中断。

char    stmt[163840+1]; // allocation a lot of memory
char    stmt2[163840+1]; // allocation a lot of memory

IIS是否有特殊设置以允许从C模块分配更多内存?

公开C dll函数的代码

步骤:

 1. use SetDllDirectory
 2. LoadLibrary
 3. then call my function with DLLImport
 4. FreeLibrary

NativeClassWrapper代码(简化)

[SuppressUnmanagedCodeSecurity]
public static class NativeClassWrapper
{
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern IntPtr LoadLibrary(string hModule);
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool FreeLibrary(IntPtr hModule);
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool SetDllDirectory(string lpPathName);
    [DllImport("myCDll.dll", EntryPoint = "MyFunction", ExactSpelling = false, SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
    public static extern int MyFunction(
    );
}

C代码

long MyFunction () {
    char    stmt[163840+1]; // allocation alot of memory
    char    stmt2[163840+1];
    long lReturn = 0L;
    *stmt = ''0';
    *stmt2 = ''0';
    return lReturn;
}

stackoverflow with dllimport from IIS

char    stmt[163840+1]; // allocation alot of memory
char    stmt2[163840+1];

这些分配是造成堆栈溢出的原因。您正试图在堆栈上分配大数组,但堆栈不够大。Windows应用程序的默认堆栈是1MB。数组本身不会溢出这样的堆栈。然而,IIS使用较小的堆栈,或者没有您没有显示的代码可以进行类似的大堆栈分配,这是非常合理的。

如果您真的需要分配这么大的数组,那么应该在堆上进行分配。

感谢David Heffernan的回复。我赞同他的回答,因为它帮助我找到了这个解决办法。我选择的解决方案是在不同的线程上启动与C Dll通信的进程,并将堆栈大小分配给1MB,而不是默认的256KB
public void StartNewThread()
{
    const int stacksize = 1024*1024; // 1MB
    var thread = new Thread(NativeDllProcess, stacksize);
    thread.Start();
    thread.Join(); // Wait till thread is ready
    // .. rest of code here
}
private void NativeDllProcess(object info)
{
    // ..... Code thats calls C dll functions
}

更多信息请点击此处:IIS 的最大/默认堆栈大小

默认情况下,在本机IIS进程中创建的线程的最大堆栈大小为256 KB电子邮件打印摘要默认情况下,在Windows Server 2008之前,由本机Microsoft Internet Information Services(IIS)进程创建的线程的最大堆栈大小为256 KB。例如,当Inetinfo.exe、DLLHost.exe或W3wp.exe在IIS 5.0或IIS 6.0中创建线程时,默认情况下线程的最大堆栈大小为256 KB。您也可以显式调用CreateThread函数来指定线程的堆栈大小。在Microsoft Windows 2000中,如果Microsoft ASP.NET工作进程(ASPNet_wp.exe)创建线程,则该线程的最大堆栈大小为1 MB。在Windows Server 2008及更高版本中,在32位版本的IIS上运行的线程的最大堆栈大小为256 KB,在x64服务器上运行的最大堆栈尺寸为512 KB。

注意:Internet Information Services是一个多线程web应用程序平台,允许在每个工作进程中运行的应用程序代码在必要时同时使用数百个或更多线程。每个线程都受到相同堆栈大小限制的约束,以便将进程的虚拟内存使用率保持在可管理的范围内。