C# 当从托管Dll调用时,托管Dll中出现堆栈溢出异常

C# 当从托管Dll调用时,托管Dll中出现堆栈溢出异常,c#,unmanaged,fortran,managed,C#,Unmanaged,Fortran,Managed,我的问题类似于,但有一些不同 我有一个fortran dll作为后端,一个C#exe作为前端。我使用PInvoke在它们之间传递数据 C#和fortran代码之间有22个参数。其中一些是整数、双精度、指针(C#指针)、数组等等。所以它是多种类型的混合 问题是,对于小数组,代码可以正常工作,但是对于大数组(~10k元素大小),在我的代码进入托管代码后,会立即抛出stackoverflowexception 编辑:我已经设法缩小了所有的规模。以下是fortran代码: subroutine ch

我的问题类似于,但有一些不同

我有一个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(546547)
,我会得到一个stackoverflowexception


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

我对此相当困惑,但一些谷歌搜索似乎表明,在托管应用程序中“轻松”更改堆栈大小是不可能的。这可能是因为我缺乏知识,无法理解为什么这并不重要。但是如果从主线程调用名为
editbin.exe
的实用程序,似乎可以增加堆栈大小。如果对创建的单独线程进行调用,则可以指定堆栈大小。谈到它。

您没有提到编译Fortran时使用的是什么,但很明显,当您分配数组时,内存正在堆栈上分配,这是一件非常糟糕的事情。NET假定堆栈上的大部分内容都很小,如对象引用或整数,因此默认为1MB堆栈大小

您的示例中的298662双精度(每个可能是8或10字节)在2-3MB的范围内,这超过了1MB的堆栈大小

我找到了对“英特尔Fortran编译器”选项的引用:


它说,通过将/heap数组传递给编译器,可以避免在堆栈上分配数组。我希望其他Fortran编译器也有类似的功能,或者默认使用堆数组。

请提供更多详细信息。造成这种情况的原因有很多。关于stackoverflow的stackoverflow问题?我不同意。@tsink,我将在缩小问题规模后提供一个示例程序。@stimms,是的,stackoverflow上的stackoverflow问题将导致无限递归,这是stackoverflow的一个来源。stackoaverflow是自我永存的。