2010-03-24 46 views
2

我的問題與this one here類似,但有一些差異。當從管理DLL調用Umanaged Dll時StackOverflow異常

我有一個fortran dll作爲後端,並且C#exe作爲前端。我使用PInvoke在它們之間傳遞數據。

C#和Fortran代碼之間有22個參數。其中一些是整數,雙精度型,指針(C#指針),數組和什麼的。所以這是一種混合類型。

問題是,對於小型數組,代碼工作正常,但是,對於大型數組(〜10k元素大小),在我的代碼進入托管代碼後立即拋出了一個stackoverflowexception。

編輯:我設法縮小了一切。這裏的Fortran代碼:

subroutine chartest(maxncv,ldv) 

    !DEC$ ATTRIBUTES DLLEXPORT::chartest 
    !DEC$ ATTRIBUTES ALIAS:'chartest'::chartest 
    !DEC$ ATTRIBUTES VALUE :: maxncv,ldv 

&  

    integer, intent(in) :: maxncv, ldv 

    Double precision 
&     v(ldv,maxncv),d(maxncv,2) 

    print *, 'hello' 

    end 

這是我的C#聲明:

public static extern void chartest(

     [MarshalAs(UnmanagedType.I4)] int maxncv, 
      [MarshalAs(UnmanagedType.I4)] int ldv 


    ); 

如果我打電話chartest(546, 547),我會得到一個stackoverflowexception。

546*547=298662,這似乎不是很多元素,不是?

+0

請給出更多細節。有很多原因可以導致這種情況。 – tsinik 2010-03-24 02:40:25

+3

在stackoverflow上的stackoverflow問題?我不贊成。 – stimms 2010-03-24 02:44:36

+0

@tsink,我會在縮小問題後提供示例程序。 – Graviton 2010-03-24 02:45:29

回答

2

你沒有提到你在編譯你的Fortran,但很明顯,當你分配數組時,這個內存被分配到堆棧上,這是非常糟糕的事情。 .NET假定堆棧中的大部分東西都很小,如對象引用或整數,所以它默認爲1 MB堆棧大小。

您的298662雙打示例(每個大概8或10個字節)都在2-3 MB的範圍內,超過了1MB的堆棧大小。

,我發現了英特爾Fortran編譯器選項參考:

http://software.intel.com/en-us/forums/showthread.php?t=53881

它說,你可以避開傳遞/堆陣列編譯器在棧上分配陣列。我希望其他Fortran編譯器會有類似的東西,或者默認使用堆陣列。

1

我對此感到困惑不解,但是一些Google使用似乎表明,不可能「輕鬆」更改託管應用程序中的堆棧大小。這可能是因爲我缺乏知識,使我無法理解爲什麼這不重要。但是,如果從主線程調用它,似乎可以使用名爲editbin.exe的實用程序來增加堆棧大小。如果您在創建的單獨線程上進行調用,則可以指定堆棧大小。 This blog post談論它。