从C调用Fortran函数时的EXC_BAD_ACCESS

时间:2013-01-03 01:30:42

标签: c fortran fortran-iso-c-binding

我环顾四周,虽然有很多EXC_BAD_ACCESS问题,但都没有帮助。

我正在使用Mountain Lion(我认为OSX 10.8?)和PGI 12。

我似乎无法从C调用fortran函数,我写了一个简化的案例,似乎我无法传递整数。

我的fortran功能是:

  1 integer function smallFortran(a) result(res) bind(c,name='smallFortran_')
  2 !integer function smallFortran(a) result(res)
  3     
  4     use ISO_C_BINDING
  5     implicit none
  6     
  7     integer(kind=c_int), intent(IN) :: a
  8     !integer, intent(IN) :: a
  9     
 10     print *,'A = ', a
 11     res = a;
 12 
 13 endfunction smallFortran

我的C函数是,

int main() {
   int ier=7;
   ier = smallFortran_(8);
}

构建它..

matt@pontus:diffFst$ make                                                                                                               
pgcc -c cDoDiffFst.c                                                                                                                    
PGC-W-0267-#warning --  "Unsupported compiler detected" (/usr/include/sys/cdefs.h: 81)                                                  
PGC/x86-64 OSX 12.9-0: compilation completed with warnings                                                                              
pgcc -g -O0 -traceback -o cDoDiffFst cDoDiffFst.o smallFortran.o -lpgf90 -lpghpf2 -lpgf90rtl -lpgftnrtl -lpghpf_rpm

(我希望警告不是导致我出现问题的原因,PGI user forum通过说他们会发送更新版本的文件来回应这个问题,但我还没有回复。想法为什么PGI需要指定这么多额外的库)

当我在调试器中运行它时..

matt@pontus:diffFst$ gdb cDoDiffFst                                                                                                     
(gdb) run
Starting program: /Users/matt/aurams/trunk/utils/diffFst/cDoDiffFst 
Reading symbols for shared libraries +............................. done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000008
0x0000000100001906 in _smallFortran_ (a=Cannot access memory at address 0x8
) at smallFortran.f90:10
10              print *,'A = ', a
(gdb)

我完全迷失了,为什么我不能发送一个int?我已经尝试将值赋给整数并发送它,没有骰子。我已经尝试过它作为一个子程序,我尝试过没有返回值......没有任何作用。

2 个答案:

答案 0 :(得分:5)

这是一个替代解决方案,展示了如何编写Fortran以匹配问题的原始C.关键是声明中的value限定符。使用Fortran ISO C绑定,您可以匹配C传递参数的各种方式。您也可以在常规名称中删除下划线...这是name bind关键字的目的。

呼叫中没有下划线的C代码:

int main() {
   int ier=7;
   ier = smallFortran (8);
}

和匹配的Fortran:

function smallFortran(a) result(res) bind(c,name='smallFortran')

     use ISO_C_BINDING
     implicit none

     integer(kind=c_int), intent(IN), value :: a
     integer(kind=c_int) :: res

     print *,'A = ', a
     res = a;

 endfunction smallFortran

答案 1 :(得分:3)

错误应该弄清楚出了什么问题; smallFortran_期望它的参数通过引用传递(就像fortran中的所有参数一样 - 请注意我在这里略微快速和松散),并尝试访问指针8处的数据,哪个失败了。修复很容易;函数需要一个指针,所以给它一个:

int main() {
  int ier = 7;
  int arg = 8;
  ier = smallFortran_(&arg);
}

这假设fortran integer类型对应于有问题的编译器的C int;您可能需要另外arg long