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

发布于 2024-10-07 14:48:32 字数 692 浏览 2 评论 0原文

我有一个现有的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

埖埖迣鎅 2024-10-14 14:48:32

您的 [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.

梦魇绽荼蘼 2024-10-14 14:48:32

根据我的经验,如果您有类似以下的 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。

My experience would say if you have a FORTRAN declaration like:

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

Perhaps you should try the following:

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文