我有一个现有的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窗体中创建相同的示例,它不会崩溃。
答案 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.