Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C调用Fortran函数时EXC_访问错误_C_Fortran_Fortran Iso C Binding - Fatal编程技术网

从C调用Fortran函数时EXC_访问错误

从C调用Fortran函数时EXC_访问错误,c,fortran,fortran-iso-c-binding,C,Fortran,Fortran Iso C Binding,我环顾了一下四周,虽然有很多EXC_BAD_访问问题,但都没有起到作用 我使用的是山狮(我想是OSX10.8吧?)和PGI12 我似乎无法从C中调用fortran函数,我已经编写了一个简化的案例,似乎无法传递整数 我的fortran函数是: 1 integer function smallFortran(a) result(res) bind(c,name='smallFortran_') 2 !integer function smallFortran(a) result(res)

我环顾了一下四周,虽然有很多EXC_BAD_访问问题,但都没有起到作用

我使用的是山狮(我想是OSX10.8吧?)和PGI12

我似乎无法从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需要指定这么多额外的库)

当我在调试器中运行它时

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?我试着给一个整数赋值并发送它,没有骰子。我试过把它作为一个子程序,我试过了,没有返回值。。什么都不管用。

这个错误应该清楚地表明出了什么问题
smallFortran_uquo;
希望它的参数通过引用传递(fortran中的所有参数都是这样——注意,我在这里有点快而且松散),并尝试访问指针
8
处的数据,但失败了。修复很容易;函数需要一个指针,因此请为它指定一个:

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

这假设fortran
integer
类型对应于有问题的编译器的C
int
;您可能需要设置
arg
a
long
,否则。

该错误应能清楚地说明问题所在
smallFortran_uquo;
希望它的参数通过引用传递(fortran中的所有参数都是这样——注意,我在这里有点快而且松散),并尝试访问指针
8
处的数据,但失败了。修复很容易;函数需要一个指针,因此请为它指定一个:

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

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

这里有一个替代解决方案,说明如何编写Fortran以匹配问题的原始C。键是声明上的
限定符。使用Fortran ISO C绑定,可以匹配C传递参数的各种方式。您还可以取消例程名称中的下划线。。。这就是
bind
name
关键字的用途

调用中不带下划线的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

这里有一个替代解决方案,展示了如何编写Fortran来匹配问题的原始C语言。键是声明上的
限定符。使用Fortran ISO C绑定,可以匹配C传递参数的各种方式。您还可以取消例程名称中的下划线。。。这就是
bind
name
关键字的用途

调用中不带下划线的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

有太多的事情会出错。。。。一个是C和Fortran通常使用不同的参数传递协议——C是按值传递的,Fortran通常(取决于编译器和其他问题)是按引用传递的。@HotLicks-Hmm,没有这样想过。也许我可以尝试传递int作为引用?(我的C不好,我会尝试作为一个指针,并通过引用)有太多的事情会出错。。。。一个是C和Fortran通常使用不同的参数传递协议——C是按值传递的,Fortran通常(取决于编译器和其他问题)是按引用传递的。@HotLicks-Hmm,没有这样想过。也许我可以尝试传递int作为引用?(我的C不好,我会尝试作为一个指针,并通过引用)@hotLicks评论让我注意到(现在看起来很明显,但我完全错过了。)谢谢!我现在正在尝试,并将公布我的结果。(为此苦苦挣扎了一段时间,所以我很期待得到回应。我不擅长C语言,也不熟悉C和fortran的混合,所以这可能就是我没有注意到的原因。:()谢谢!@hotLicks的评论让我注意到了这一点(现在似乎很明显,但我完全错过了。)谢谢!我现在正在尝试,并将发布我的结果。(为此我苦苦挣扎了一段时间,所以我很期待得到回应。我不擅长C,也不熟悉C和fortran的混合,所以这可能就是我没有注意到的原因。:()谢谢!