从C#调用Fortran dll函数的堆栈溢出异常

时间:2010-12-16 15:36:42

标签: .net dll fortran wrapper

我有一个现有的VB6程序,它使用以下定义调用Fortran dll:

Declare Function START Lib "BackEndLib2.dll" Alias "_START@0" () As Integer

我们正在将VB6应用程序迁移到C#(。net 4.0),现在定义如下:

[DllImport("BackEndLib2.dll", EntryPoint = "_START@0")]
public static extern short START();

但是,当我在c#中调用相同的函数调用时,它会成功执行dll调用,返回托管代码并在一段时间后抛出堆栈溢出异常。

我也在VB.net中尝试了相同的dll调用,结果相同:

Declare Function START Lib "BackEndLib2.dll" Alias "_START@0" () As Short

知道为什么同一个函数调用在.NET 4.0中产生堆栈溢出异常但在vb6中成功运行?

我猜我正在使用dll调用破坏堆栈,但我不确定。我尝试了很多不同的参数类型,但到目前为止还没有任何工作。

编辑:这似乎只是WPF中的问题,如果我在Windows窗体中创建相同的示例,它不会崩溃。

2 个答案:

答案 0 :(得分:2)

您的[DllImport]声明等同于VB6声明语句。可能最好假设VB6声明是错误的开始,你运气好了。返回类型很奇怪,但是这不会导致堆栈问题,因为返回值是通过CPU寄存器传递的,而不是堆栈。

使用Debug + Windows + Registers开始诊断。在通话前后注意ESP的价值。如果它不相同那么你确实有一个声明问题,并且许多对此函数的调用可能会导致堆栈崩溃。不太可能btw,这通常会产生MDA警告。如果它匹配则它只能是溢出堆栈的Fortran代码。

另请注意,您可能会指责错误的功能。生成SOE的功能可能不是拧紧堆栈的功能。查看ESP值可以让您快速找到麻烦制造者。

答案 1 :(得分:0)

如果您有FORTRAN声明,我的经验会说:

        INTEGER*4 FUNCTION START( )
CDEC$ATTRIBUTES STDCALL, DLLEXPORT :: START
C.....  BODY HERE
        ENDFUNCTION

也许您应该尝试以下方法:

[DllImport(..., CallingConvention = CallingConvention.StdCall)]
public static extern int Start( );

出于好奇,哪个FORTRAN编译器生成了那个DLL?您是否指定应将其导出为STDCALL?您可能还必须将调用约定更改为C.