【发布时间】:2012-06-21 04:22:47
【问题描述】:
我有一个重复调用 C 函数的 Fortran 90 程序。第一次使用该函数一切顺利,但第二次代码尝试访问该函数时出现以下错误:
程序收到信号 SIGSEGV:分段错误 - 内存引用无效。
我在 Windows 上使用 gfortran v.4.6,链接到我没有源代码的库。该库以 DLL 的形式出现在我面前,我使用 gendef 和 dlltool 创建了一个要链接的 .a 库。
代码如下:
PROGRAM cmod
USE, INTRINSIC :: ISO_C_BINDING
INTERFACE
LOGICAL (C_BOOL) FUNCTION clover(scen,reg,soil,top,rain,depth,numd,nums,numb, numd,addn,srate,stype,nloss,ploss,ErrStr) BIND (C, name = "ClOvr")
USE, INTRINSIC :: ISO_C_BINDING
INTEGER (C_INT), INTENT(IN), VALUE :: scen,reg,soil,topo,depth
REAL (C_DOUBLE), INTENT(IN), VALUE :: rain,numd,nums,numb,numd
REAL (C_DOUBLE), INTENT(IN), VALUE :: addn,srate
INTEGER (C_INT), INTENT(IN), VALUE :: stype
REAL (C_DOUBLE), INTENT(OUT) :: nloss,ploss
CHARACTER(C_CHAR), INTENT(OUT) :: ErrStr(*)
END FUNCTION clover
END INTERFACE
.....
do
.....
result = clover(a,b,c, d, e, f, g, h, sb, sd, an, sr, st,lossx,lossy,err)
......
result = clover(a,b,c, d, e, f, g, h, sb, sd, an, sr, st,lossx,lossy,err)
end do
END PROGRAM cmod
我没有 C 代码,但我从 IBM Fortran 移植。
接口声明包含这两行
!DEC$ ATTRIBUTES VALUE :: scen,reg,soil,top,rain,depth,numd,nums,numb,numd,addn,srate,stype
!DEC$ ATTRIBUTES REFERENCE :: lossx,lossy,ErrStr
IBM fortran 使用以下代码加载库并访问函数:
pointer (q,clover)
p = loadlibrary("clover.dll")
q = getprocaddress(p, "ClOvr")
所以我可能在翻译 GNU fortran 时遗漏了一些东西
【问题讨论】:
-
C 函数一定已经崩溃了。但是您没有提供有助于理解原因的信息。
-
提供 C 函数会有所帮助。检查变量周围的代码,您可能会在那里找到错误/修复。
-
您如何在 Windows 上获得 SIGSEGV?你得到核心转储了吗?
-
@cdarke,令人惊讶的是,Windows CRT 库支持
SIGSEGV,请参阅 here,尽管在可用的最旧文档版本(VS .NET 2003)中写到SIGSEGV是为了兼容仅但仍然可以由raise()生成。 -
@cdrake,我和你一样震惊 :) 我什至用一个简单的程序对它进行了测试,该程序在发布模式下取消引用未初始化的指针 - 看起来 CRT 正在将
EXC_BAD_ACCESS转换为 @987654329 @ 如果安装了信号处理程序。
标签: c segmentation-fault gfortran