【问题标题】:Function call crash fixed by print statements打印语句修复的函数调用崩溃
【发布时间】:2014-03-11 21:47:30
【问题描述】:

我正在使用 Visual Studio 2012 和 intel fortran 2013 在 Windows 上编译 Fortran 程序。在程序中,我调用了一个 C 函数,它是静态库的一部分:

call myfunction(arg1,arg2,...);

当我在调试模式下运行时,一切都很好。当我在发布模式下运行它时,程序在该函数调用期间崩溃(我通过在调用之前/之后打印到屏幕来测试它)并出现以下错误:

forrtl: severe (157): Program Exception - access violation

现在有趣的部分,如果我在调用前后添加打印语句,如下所示

print 'Calling myfunction'
call myfunction(arg1,arg2,...);
print 'myfunction finished'

程序在发布模式下完美运行。如果我删除任何一个打印语句(或两个),我会收到上述错误!

有人知道这里会发生什么吗?

更多信息:

Fortran 中的函数声明为:

!DEC$ ALIAS  myfunction, 'myfunction'

C 中的函数声明为:

extern "C" void myfunction(double *arg1, double *arg2, ...)

【问题讨论】:

  • 请改进问题标题
  • 1) 它是可变参数函数吗? 2) 你是如何在 Fortran 中声明 myfunction 的? 3) myfunction 是如何在 C - __stdcall 或 __cdecl 中声明的?
  • 抱歉,什么是可变参数函数?
  • 对不起,你是一块一块地改。只需显示实际代码。

标签: fortran intel-fortran


【解决方案1】:

这是堆栈损坏的常见症状。可能,您使用错误的参数调用myfunction,但它可能在其中更深的某个地方。检查每个调用并检查所有参数的类型。

调试时请务必将-check all-warn all 与ifort 一起使用。其中包括-warn interfaces,它对类似的问题非常有帮助,但由于您调用的是 C 函数,因此可能无法在此处找到原因。

编辑 - 对于 2 个参数子例程:

根据您使用的声明类型,请确保两个参数都是 double precisionc_doublereal*8。不要在那里放置任何第三个参数,因为您的第一段代码可能会建议!

Fortran 2003 中连接它的现代方式是:

interface
  subroutine myfunction(arg1, arg2) bind(C, name="myfunction")
    use iso_c_binding
    real(c_double) :: arg1, arg2
  end subroutine
end interface

在代码的声明部分中,它代替了旧的(和可选的)external myfunction

无论如何,请仔细检查所有参数的类型和正确位置,无论它们的最终数量是多少。

【讨论】:

  • 对不起,混淆了,...只是表示我实际上有比 2 更多的参数(它有 10 个参数,整数和实数的混合)
  • 我想这确实会教我按照您所说的放置实际代码,一位同事更新了 C 库并在函数定义中添加了一个参数......这解释了我的问题。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-14
  • 1970-01-01
相关资源
最近更新 更多