2015-11-02 70 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應用程序平臺,使每個工作進程內部運行的應用程序代碼來一次必要利用數百個或更多的線程。每個線程都受到相同的堆棧大小限制,以便將進程的虛擬內存使用量保持在可管理的限制範圍內。