从 C# 调用 Fortran dll 函数时出现堆栈溢出异常
我有一个现有的 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 窗体中创建相同的示例,它不会崩溃。
I have an existing VB6 program that calls a Fortran dll with the following definition:
Declare Function START Lib "BackEndLib2.dll" Alias "_START@0" () As Integer
We are in the process of migrating the VB6 application to C# (.net 4.0) and the definition is now as follows:
[DllImport("BackEndLib2.dll", EntryPoint = "_START@0")]
public static extern short START();
However, when I call the same function call in c#, it executes the dll call successfully returns to managed code and than throws a stack overflow exception after a while.
I also tried the same dll call in VB.net with the same result:
Declare Function START Lib "BackEndLib2.dll" Alias "_START@0" () As Short
Any idea why the same function call yields a stack overflow exception in .NET 4.0 but works successfully in vb6?
I'm guessing I'm corrupting the stack with the dll call but I'm not sure. I tried many different parameter types but nothing has worked so far.
Edit: This only seems to be an issue in WPF and if I create the same sample in Windows Forms it does not crash.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的 [DllImport] 声明相当于 VB6 声明语句。最好假设 VB6 声明一开始就是错误的,并且您幸运地逃脱了它。返回类型很奇怪,但这不会导致堆栈问题,因为返回值是通过 CPU 寄存器而不是堆栈传递的。
使用“调试”+“Windows”+“寄存器”开始诊断此问题。注意调用前后ESP的值。如果不一样,那么确实存在声明问题,并且对该函数的大量调用可能会破坏堆栈。顺便说一句,这不太可能,这通常会生成 MDA 警告。如果匹配,则只能是溢出堆栈的 Fortran 代码。
另请记住,您可能会归咎于错误的功能。生成 SOE 的函数可能不是导致堆栈混乱的函数。查看 ESP 值可以让您快速找到麻烦制造者。
Your [DllImport] declaration is equivalent to the VB6 declare statement. It is probably best to assume that the VB6 declaration was wrong to begin with an that you got away with it by luck. The return type is quite odd, but that can't cause a stack problem since the return value is passed through a CPU register, not the stack.
Start diagnosing this with Debug + Windows + Registers. Pay attention to the value of ESP before and after the call. If it is not the same then you really do have a declaration problem and lots of calls to this function can blow the stack. Not that likely btw, this normally generates an MDA warning. If it matches then it can only be the Fortran code that overflows the stack.
Also keep in mind that you might be blaming the wrong function. The function that generates the SOE might not be the one that screwed the stack up. Looking at the ESP value lets you quickly find the trouble-maker.
根据我的经验,如果您有类似以下的 FORTRAN 声明:
也许您应该尝试以下操作:
出于好奇,哪个 FORTRAN 编译器生成了该 DLL?您是否指定应将其导出为 STDCALL?您可能还必须将调用约定更改为 C。
My experience would say if you have a FORTRAN declaration like:
Perhaps you should try the following:
Out of curiosity, which FORTRAN compiler generated that DLL? Did you specify that it should be exported as STDCALL? You may have to change the calling convention to C as well.