2015-11-02 71 views
-2

方案计算器与dllimport的从IIS

我做了一个包装类的C DLL,所以我可以从托管代码调用它的功能,我可以从C#WCF服务访问它们。 Everyting似乎很好,但是在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代码(Simplefied)

[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; 
} 
+0

为什么对这个问题 – lordkain

+0

负显然,在你的代码中的缺陷。你没有显示任何重要的代码。因此你必须自己调试它。如果您需要帮助,请提供[mcve]和诊断。 –

+0

感谢大卫,我更新了示例 – lordkain

回答

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

这些分配负责堆栈​​溢出。您正试图在堆栈上分配大型数组,并且堆栈不够大。 Windows应用程序的默认堆栈为1MB。数组本身不会溢出这样的堆栈。但是,IIS使用较小的堆栈或者没有显示出类似的大堆栈分配的代码是非常合理的。

如果你真的需要分配这么大的数组,你应该在堆上这样做。

+0

有没有办法让IIS分配这个内存? (实际上,有更多的数组在16384堆栈中分配内存,而不是2分配163840,但是对于这个例子来说,它是合适的。) – lordkain

+0

很可能。请记住,我不知道你在努力达到什么目标,也不适合就如何编写程序的其他部分提供建议。我只是回答你问的问题。我正在解释为什么你有堆栈溢出错误。 –

+0

谢谢你的回答。一个collega引用我这个链接https://support.microsoft.com/en-us/kb/932909 IIS在每个线程声称256Kb。恐怕我的dll需要更多。所以作为解决方案,我会用一个线程来包装我的dll,这个线程声称更多的内存到堆栈。我会告诉你 – lordkain

0

感谢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 
} 

这里的更多信息: maximum/default stack size IIS

默认情况下,在本地IIS进程中创建的线程的最大堆栈大小为256 KB 电子邮件 打印 摘要 默认情况下,由本机Microsoft Internet信息服务(IIS)创建的线程的最大堆栈大小Windows之前的进程为256 KB Server 2008.例如,当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信息服务是一个多线程的Web应用程序平台,使每个工作进程内部运行的应用程序代码来一次必要利用数百个或更多的线程。每个线程都受到相同的堆栈大小限制,以便将进程的虚拟内存使用量保持在可管理的限制范围内。